(Draft) OpenFlow 1.5 flow mod commands include commands to manipulate the buckets of existing groups. This patch add support to ovs-ofctl for these commands. It also adds documentation and tests for them.
ONF-JIRA: EXT-350 Signed-off-by: Simon Horman <simon.hor...@netronome.com> --- v3 * As suggested by Ben Pfaff - Correct --help text: file-based forms require a redirect in the same way as the existing del-groups command v2 * As suggested by Ben Pfaff - Use ONF-JIRA: EXT-350 annotation in changelog --- tests/ofproto.at | 94 ++++++++++++++++++++++++++++++++++++++++++++++++ utilities/ovs-ofctl.8.in | 57 +++++++++++++++++++++++++++-- utilities/ovs-ofctl.c | 18 ++++++++++ 3 files changed, 166 insertions(+), 3 deletions(-) diff --git a/tests/ofproto.at b/tests/ofproto.at index 720ceb7..5964113 100644 --- a/tests/ofproto.at +++ b/tests/ofproto.at @@ -390,6 +390,100 @@ AT_CLEANUP dnl This is really bare-bones. dnl It at least checks request and reply serialization and deserialization. +dnl Actions definition listed in both supported formats (w/ actions=) +AT_SETUP([ofproto - insert buckets]) +OVS_VSWITCHD_START +AT_DATA([groups.txt], [dnl +group_id=1234,type=all,bucket=bucket_id:10,actions=output:10,bucket=bucket_id:11,actions=output:11 +]) +AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn add-groups br0 groups.txt]) +AT_CHECK([ovs-ofctl -F OXM-OpenFlow15 -O OpenFlow15 -vwarn dump-groups br0 1234], [0], [stdout]) +AT_CHECK([STRIP_XIDS stdout], [0], [dnl +OFPST_GROUP_DESC reply (OF1.5): + group_id=1234,type=all,bucket=bucket_id:10,actions=output:10,bucket=bucket_id:11,actions=output:11 +]) +AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn insert-buckets br0 group_id=1234,command_bucket_id=first,bucket=bucket_id:0,actions=output:0,bucket=bucket_id:1,actions=output:1]) +AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn dump-groups br0], [0], [stdout]) +AT_CHECK([STRIP_XIDS stdout], [0], [dnl +OFPST_GROUP_DESC reply (OF1.5): + group_id=1234,type=all,bucket=bucket_id:0,actions=output:0,bucket=bucket_id:1,actions=output:1,bucket=bucket_id:10,actions=output:10,bucket=bucket_id:11,actions=output:11 +]) +AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn insert-buckets br0 group_id=1234,command_bucket_id=last,bucket=bucket_id:14,actions=output:14,bucket=bucket_id:15,actions=output:15]) +AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn dump-groups br0], [0], [stdout]) +AT_CHECK([STRIP_XIDS stdout], [0], [dnl +OFPST_GROUP_DESC reply (OF1.5): + group_id=1234,type=all,bucket=bucket_id:0,actions=output:0,bucket=bucket_id:1,actions=output:1,bucket=bucket_id:10,actions=output:10,bucket=bucket_id:11,actions=output:11,bucket=bucket_id:14,actions=output:14,bucket=bucket_id:15,actions=output:15 +]) +AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn insert-buckets br0 group_id=1234,command_bucket_id=15]) +AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn dump-groups br0], [0], [stdout]) +AT_CHECK([STRIP_XIDS stdout], [0], [dnl +OFPST_GROUP_DESC reply (OF1.5): + group_id=1234,type=all,bucket=bucket_id:0,actions=output:0,bucket=bucket_id:1,actions=output:1,bucket=bucket_id:10,actions=output:10,bucket=bucket_id:11,actions=output:11,bucket=bucket_id:14,actions=output:14,bucket=bucket_id:15,actions=output:15 +]) +AT_DATA([buckets.txt], [dnl +group_id=1234,command_bucket_id=11,bucket=bucket_id:12,actions=output:12,bucket=bucket_id:13,actions=output:13 +]) +AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn insert-buckets br0 - < buckets.txt]) +AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn dump-groups br0], [0], [stdout]) +AT_CHECK([STRIP_XIDS stdout], [0], [dnl +OFPST_GROUP_DESC reply (OF1.5): + group_id=1234,type=all,bucket=bucket_id:0,actions=output:0,bucket=bucket_id:1,actions=output:1,bucket=bucket_id:10,actions=output:10,bucket=bucket_id:11,actions=output:11,bucket=bucket_id:12,actions=output:12,bucket=bucket_id:13,actions=output:13,bucket=bucket_id:14,actions=output:14,bucket=bucket_id:15,actions=output:15 +]) +AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn insert-buckets br0 group_id=1234,command_bucket_id=15,bucket=bucket_id:20,actions=output:20,bucket=bucket_id:21,actions=output:21]) +AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn dump-groups br0], [0], [stdout]) +AT_CHECK([STRIP_XIDS stdout], [0], [dnl +OFPST_GROUP_DESC reply (OF1.5): + group_id=1234,type=all,bucket=bucket_id:0,actions=output:0,bucket=bucket_id:1,actions=output:1,bucket=bucket_id:10,actions=output:10,bucket=bucket_id:11,actions=output:11,bucket=bucket_id:12,actions=output:12,bucket=bucket_id:13,actions=output:13,bucket=bucket_id:14,actions=output:14,bucket=bucket_id:15,actions=output:15,bucket=bucket_id:20,actions=output:20,bucket=bucket_id:21,actions=output:21 +]) +OVS_VSWITCHD_STOP +AT_CLEANUP + +dnl This is really bare-bones. +dnl It at least checks request and reply serialization and deserialization. +dnl Actions definition listed in both supported formats (w/ actions=) +AT_SETUP([ofproto - remove buckets]) +OVS_VSWITCHD_START +AT_DATA([groups.txt], [dnl +group_id=1234,type=all,bucket=bucket_id:10,actions=output:10,bucket=bucket_id:11,actions=output:11,bucket=bucket_id:12,actions=output:12,bucket=bucket_id:13,actions=output:13,bucket=bucket_id:14,actions=output:14,bucket=bucket_id:15,actions=output:15,bucket=bucket_id:16,actions=output:16 +]) +AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn add-groups br0 groups.txt]) +AT_CHECK([ovs-ofctl -F OXM-OpenFlow15 -O OpenFlow15 -vwarn dump-groups br0 1234], [0], [stdout]) +AT_CHECK([STRIP_XIDS stdout], [0], [dnl +OFPST_GROUP_DESC reply (OF1.5): + group_id=1234,type=all,bucket=bucket_id:10,actions=output:10,bucket=bucket_id:11,actions=output:11,bucket=bucket_id:12,actions=output:12,bucket=bucket_id:13,actions=output:13,bucket=bucket_id:14,actions=output:14,bucket=bucket_id:15,actions=output:15,bucket=bucket_id:16,actions=output:16 +]) +AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn remove-buckets br0 group_id=1234,command_bucket_id=first]) +AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn dump-groups br0], [0], [stdout]) +AT_CHECK([STRIP_XIDS stdout], [0], [dnl +OFPST_GROUP_DESC reply (OF1.5): + group_id=1234,type=all,bucket=bucket_id:11,actions=output:11,bucket=bucket_id:12,actions=output:12,bucket=bucket_id:13,actions=output:13,bucket=bucket_id:14,actions=output:14,bucket=bucket_id:15,actions=output:15,bucket=bucket_id:16,actions=output:16 +]) +AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn remove-buckets br0 group_id=1234,command_bucket_id=last]) +AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn dump-groups br0], [0], [stdout]) +AT_CHECK([STRIP_XIDS stdout], [0], [dnl +OFPST_GROUP_DESC reply (OF1.5): + group_id=1234,type=all,bucket=bucket_id:11,actions=output:11,bucket=bucket_id:12,actions=output:12,bucket=bucket_id:13,actions=output:13,bucket=bucket_id:14,actions=output:14,bucket=bucket_id:15,actions=output:15 +]) +AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn remove-buckets br0 group_id=1234,command_bucket_id=13]) +AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn dump-groups br0], [0], [stdout]) +AT_CHECK([STRIP_XIDS stdout], [0], [dnl +OFPST_GROUP_DESC reply (OF1.5): + group_id=1234,type=all,bucket=bucket_id:11,actions=output:11,bucket=bucket_id:12,actions=output:12,bucket=bucket_id:14,actions=output:14,bucket=bucket_id:15,actions=output:15 +]) +AT_DATA([buckets.txt], [dnl +group_id=1234 +]) +AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn remove-buckets br0 - < buckets.txt]) +AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn dump-groups br0], [0], [stdout]) +AT_CHECK([STRIP_XIDS stdout], [0], [dnl +OFPST_GROUP_DESC reply (OF1.5): + group_id=1234,type=all +]) +OVS_VSWITCHD_STOP +AT_CLEANUP + +dnl This is really bare-bones. +dnl It at least checks request and reply serialization and deserialization. AT_SETUP([ofproto - flow mod checks group availability]) OVS_VSWITCHD_START AT_CHECK([ovs-ofctl -O OpenFlow11 -vwarn add-group br0 group_id=1234,type=all,bucket=output:10]) diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in index b358ec8..4641461 100644 --- a/utilities/ovs-ofctl.8.in +++ b/utilities/ovs-ofctl.8.in @@ -385,6 +385,18 @@ Deletes entries from \fIswitch\fR's group table. With only a \fIswitch\fR argument, deletes all groups. Otherwise, deletes the group for each group entry. . +.IP "\fBinsert\-buckets \fIswitch group\fR" +.IQ "\fBinsert\-buckets \fIswitch \fB\- < \fIfile\fR" +Add buckets to an existing group present in the \fIswitch\fR's group table. +If no \fIcommand_bucket_id\fR is present in the group specification then all +buckets of the group are removed. +. +.IP "\fBremove\-buckets \fIswitch group\fR" +.IQ "\fBremove\-buckets \fIswitch \fB\- < \fIfile\fR" +Remove buckets to an existing group present in the \fIswitch\fR's group table. +If no \fIcommand_bucket_id\fR is present in the group specification then all +buckets of the group are removed. +. .SS "OpenFlow Switch Monitoring Commands" . .IP "\fBsnoop \fIswitch\fR" @@ -1930,9 +1942,9 @@ This field is required. .IP \fBtype=\fItype\fR -The type of the group. This \fBadd-group\fR, \fBadd-groups\fR and -\fBdel-groups\fR command require this field. The following keywords -designated the allowed types: +The type of the group. The \fBadd-group\fR, \fBadd-groups\fR and +\fBdel-groups\fR commands require this field. It is prohibited for +other commands. The following keywords designated the allowed types: .RS .IP \fBall\fR Execute all buckets in the group. @@ -1949,6 +1961,45 @@ Executes the first live bucket in the group which is associated with a live port or group. .RE +.IP \fBcommand_bucket_id=\fIid\fR +The bucket to operate on. The \fBinsert-buckets\fR and \fBremove-buckets\fR +commands require this field. It is prohibited for other commands. +\fIid\fR may be an integer or one of the following keywords: +.RS +.IP \fBall\fR +Operate on all buckets in the group. +Only valid when used with the \fBremove-buckets\fR command in which +case the effect is to remove all buckets from the group. +.IP \fBfirst\fR +Operate on the first bucket present in the group. +In the case of the \fBinsert-buckets\fR command the effect is to +insert new bucets just before the first bucket already present in the group; +or to replace the buckets of the group if there are no buckets already present +in the group. +In the case of the \fBremove-buckets\fR command the effect is to +remove the first bucket of the group; or do nothing if there are no +buckets present in the group. +.IP \fBlast\fR +Operate on the last bucket present in the group. +In the case of the \fBinsert-buckets\fR command the effect is to +insert new bucets just after the last bucket already present in the group; +or to replace the buckets of the group if there are no buckets already present +in the group. +In the case of the \fBremove-buckets\fR command the effect is to +remove the last bucket of the group; or do nothing if there are no +buckets present in the group. +.RE +.IP +If \fIid\fR is an integer then it should correspond to the \fBbucket_id\fR +of a bucket present in the group. +In case of the \fBinsert-buckets\fR command the effect is to +insert buckets just before the bucket in the group whose \fBbucket_id\fR is +\fIid\fR. +In case of the \fBiremove-buckets\fR command the effect is to +remove the in the group whose \fBbucket_id\fR is \fIid\fR. +It is an error if there is no bucket persent group in whose \fBbucket_id\fR is +\fIid\fR. + .IP \fBbucket\fR=\fIbucket_parameters\fR The \fBadd-group\fR, \fBadd-groups\fR and \fBmod-group\fR commands require at least one bucket field. Bucket fields must appear after diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index b5b9064..21da4db 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -342,6 +342,8 @@ usage(void) " add-groups SWITCH FILE add group from FILE\n" " mod-group SWITCH GROUP modify specific group\n" " del-groups SWITCH [GROUP] delete matching GROUPs\n" + " insert-buckets SWITCH [GROUP] add buckets to GROUP\n" + " remove-buckets SWITCH [GROUP] remove buckets from GROUP\n" " dump-group-features SWITCH print group features\n" " dump-groups SWITCH [GROUP] print group description\n" " dump-group-stats SWITCH [GROUP] print group statistics\n" @@ -2175,6 +2177,18 @@ ofctl_del_groups(int argc, char *argv[]) } static void +ofctl_insert_bucket(int argc, char *argv[]) +{ + ofctl_group_mod(argc, argv, OFPGC15_INSERT_BUCKET); +} + +static void +ofctl_remove_bucket(int argc, char *argv[]) +{ + ofctl_group_mod(argc, argv, OFPGC15_REMOVE_BUCKET); +} + +static void ofctl_dump_group_stats(int argc, char *argv[]) { enum ofputil_protocol usable_protocols; @@ -3547,6 +3561,10 @@ static const struct command all_commands[] = { 1, 2, ofctl_mod_group }, { "del-groups", "switch [group]", 1, 2, ofctl_del_groups }, + { "insert-buckets", "switch [group]", + 1, 2, ofctl_insert_bucket }, + { "remove-buckets", "switch [group]", + 1, 2, ofctl_remove_bucket }, { "dump-groups", "switch [group]", 1, 2, ofctl_dump_group_desc }, { "dump-group-stats", "switch [group]", -- 2.1.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev