diff options
author | Jan Scheurich <jan.scheurich@web.de> | 2016-06-29 00:29:25 +0200 |
---|---|---|
committer | Ben Pfaff <blp@ovn.org> | 2016-07-02 21:10:32 -0700 |
commit | 88b87a36123e5ce3704b5e79950e83651db43ef7 (patch) | |
tree | 09c12f1d18fe6c61453be9a2569c2ac7ed64ad53 /lib | |
parent | 2c5cbb15ff5231858df2608e8cd7ac46ff6bd78c (diff) | |
download | openvswitch-88b87a36123e5ce3704b5e79950e83651db43ef7.tar.gz |
ofproto: Add relaxed group_mod command ADD_OR_MOD
This patch adds support for a new Group Mod command OFPGC_ADD_OR_MOD to
OVS for all OpenFlow versions that support groups (OF11 and higher).
The new ADD_OR_MOD creates a group that does not yet exist (like ADD)
and modifies an existing group (like MODIFY).
Rational: In OpenFlow 1.x the Group Mod commands OFPGC_ADD and
OFPGC_MODIFY have strict semantics: ADD fails if the group exists,
while MODIFY fails if the group does not exist. This requires a
controller to exactly know the state of the switch when programming a
group in order not run the risk of getting an OFP Error message in
response. This is hard to achieve and maintain at all times in view of
possible switch and controller restarts or other connection losses
between switch and controller.
Due to the un-acknowledged nature of the Group Mod message programming
groups safely and efficiently at the same time is virtually impossible
as the controller has to either query the existence of the group prior
to each Group Mod message or to insert a Barrier Request/Reply after
every group to be sure that no Error can be received at a later stage
and require a complicated roll-back of any dependent actions taken
between the failed Group Mod and the Error.
In the ovs-ofctl command line the ADD_OR_MOD command is made available
through the new option --may-create in the mod-group command:
$ ovs-ofctl -Oopenflow13 del-groups br-int group_id=100
$ ovs-ofctl -Oopenflow13 mod-group br-int
group_id=100,type=indirect,bucket=actions=2 OFPT_ERROR (OF1.3)
(xid=0x2): OFPGMFC_UNKNOWN_GROUP OFPT_GROUP_MOD (OF1.3) (xid=0x2):
MOD group_id=100,type=indirect,bucket=actions=output:2
$ ovs-ofctl -Oopenflow13 --may-create mod-group br-int
group_id=100,type=indirect,bucket=actions=2
$ ovs-ofctl -Oopenflow13 dump-groups br-int
OFPST_GROUP_DESC reply (OF1.3) (xid=0x2):
group_id=100,type=indirect,bucket=actions=output:2
$ ovs-ofctl -Oopenflow13 --may-create mod-group br-int
group_id=100,type=indirect,bucket=actions=3
$ ovs-ofctl -Oopenflow13 dump-groups br-int
OFPST_GROUP_DESC reply (OF1.3) (xid=0x2):
group_id=100,type=indirect,bucket=actions=output:3
Signed-off-by: Jan Scheurich <jan.scheurich at web.de>
Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ofp-parse.c | 4 | ||||
-rw-r--r-- | lib/ofp-print.c | 4 | ||||
-rw-r--r-- | lib/ofp-util.c | 7 |
3 files changed, 14 insertions, 1 deletions
diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c index 71c5cdfe7..4af6d9ba2 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -1380,6 +1380,10 @@ parse_ofp_group_mod_str__(struct ofputil_group_mod *gm, uint16_t command, fields = F_GROUP_TYPE | F_BUCKETS; break; + case OFPGC11_ADD_OR_MOD: + fields = F_GROUP_TYPE | F_BUCKETS; + break; + case OFPGC15_INSERT_BUCKET: fields = F_BUCKETS | F_COMMAND_BUCKET_ID; *usable_protocols &= OFPUTIL_P_OF15_UP; diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 5747ec68f..919c95d64 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -2703,6 +2703,10 @@ ofp_print_group_mod__(struct ds *s, enum ofp_version ofp_version, ds_put_cstr(s, "MOD"); break; + case OFPGC11_ADD_OR_MOD: + ds_put_cstr(s, "ADD_OR_MOD"); + break; + case OFPGC11_DELETE: ds_put_cstr(s, "DEL"); break; diff --git a/lib/ofp-util.c b/lib/ofp-util.c index cc9f5e0ec..2b214ea3b 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -8896,6 +8896,7 @@ parse_group_prop_ntr_selection_method(struct ofpbuf *payload, switch (group_cmd) { case OFPGC15_ADD: case OFPGC15_MODIFY: + case OFPGC15_ADD_OR_MOD: break; case OFPGC15_DELETE: case OFPGC15_INSERT_BUCKET: @@ -9224,6 +9225,7 @@ bad_group_cmd(enum ofp15_group_mod_command cmd) switch (cmd) { case OFPGC15_ADD: case OFPGC15_MODIFY: + case OFPGC15_ADD_OR_MOD: case OFPGC15_DELETE: version = "1.1"; opt_version = "11"; @@ -9245,6 +9247,7 @@ bad_group_cmd(enum ofp15_group_mod_command cmd) break; case OFPGC15_MODIFY: + case OFPGC15_ADD_OR_MOD: cmd_str = "mod-group"; break; @@ -9284,7 +9287,7 @@ ofputil_encode_group_mod(enum ofp_version ofp_version, case OFP12_VERSION: case OFP13_VERSION: case OFP14_VERSION: - if (gm->command > OFPGC11_DELETE) { + if (gm->command > OFPGC11_DELETE && gm->command != OFPGC11_ADD_OR_MOD) { bad_group_cmd(gm->command); } return ofputil_encode_ofp11_group_mod(ofp_version, gm); @@ -9355,6 +9358,7 @@ ofputil_pull_ofp15_group_mod(struct ofpbuf *msg, enum ofp_version ofp_version, case OFPGC11_ADD: case OFPGC11_MODIFY: + case OFPGC11_ADD_OR_MOD: case OFPGC11_DELETE: default: if (gm->command_bucket_id == OFPG15_BUCKET_ALL) { @@ -9433,6 +9437,7 @@ ofputil_decode_group_mod(const struct ofp_header *oh, switch (gm->command) { case OFPGC11_ADD: case OFPGC11_MODIFY: + case OFPGC11_ADD_OR_MOD: case OFPGC11_DELETE: case OFPGC15_INSERT_BUCKET: break; |