NMX selection method Signed-off-by: Simon Horman <simon.hor...@netronome.com> --- lib/ofp-parse.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++ tests/ofproto.at | 4 +- utilities/ovs-ofctl.8.in | 23 ++++++++++- 3 files changed, 127 insertions(+), 3 deletions(-)
diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c index 16c7cdc..ad14d42 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -1159,6 +1159,75 @@ parse_bucket_str(struct ofputil_bucket *bucket, char *str_, } static char * WARN_UNUSED_RESULT +parse_select_group_field(char *s, struct flow *flow, struct mf_bitmap *bm, + enum ofputil_protocol *usable_protocols) +{ + char *save_ptr = NULL; + char *name; + struct match match; + + match_init_catchall(&match); + + for (name = strtok_r(s, "=, \t\r\n", &save_ptr); name; + name = strtok_r(NULL, "=, \t\r\n", &save_ptr)) { + const struct mf_field *mf = mf_from_name(name); + + if (mf) { + char *error; + const char *value_str; + union mf_value value, mask; + + value_str = strtok_r(NULL, ", \t\r\n", &save_ptr); + if (value_str) { + error = mf_parse(mf, value_str, &value, &mask); + if (error) { + return error; + } + + /* The mask cannot be all-zeros */ + if (is_all_zeros(&value, mf->n_bytes)) { + return xasprintf("%s: values are wildcards here " + "and must not be all-zeros", s); + } + + /* The values parsed are masks for fields used + * by the selection method */ + if (!mf_is_mask_valid(mf, &value)) { + return xasprintf("%s: invalid mask for field %s", + value_str, mf->name); + } + + /* The mask cannot have a mask */ + if (!is_all_ones(&mask, mf->n_bytes)) { + return xasprintf("%s: values are wildcards here " + "and cannot in turn be wildcarded", s); + } + } else { + memset(&value, '1', mf->n_bytes); + } + + mf_set_value(mf, &value, &match); + bitmap_set1(bm->bm, mf->id); + + if (is_all_ones(&value, mf->n_bytes)) { + *usable_protocols &= mf->usable_protocols_exact; + } else if (mf->usable_protocols_bitwise == mf->usable_protocols_cidr + || ip_is_cidr(value.be32)) { + *usable_protocols &= mf->usable_protocols_cidr; + } else { + *usable_protocols &= mf->usable_protocols_bitwise; + } + } else { + return xasprintf("%s: unknown field %s", s, name); + } + } + + *flow = match.flow; + + return NULL; +} + +static char * WARN_UNUSED_RESULT parse_ofp_group_mod_str__(struct ofputil_group_mod *gm, uint16_t command, char *string, enum ofputil_protocol *usable_protocols) @@ -1328,6 +1397,40 @@ parse_ofp_group_mod_str__(struct ofputil_group_mod *gm, uint16_t command, } else if (!strcmp(name, "bucket")) { error = xstrdup("bucket is not needed"); goto out; + } else if (!strcmp(name, "selection_method")) { + if (!(fields & F_GROUP_TYPE)) { + error = xstrdup("selection method is not needed"); + goto out; + } + if (strlen(value) >= NMX_MAX_SELECTION_METHOD_LEN) { + error = xasprintf("selection method is longer than %u" + " bytes long", + NMX_MAX_SELECTION_METHOD_LEN - 1); + goto out; + } + memset(gm->props.selection_method, '0', + NMX_MAX_SELECTION_METHOD_LEN); + strcpy(gm->props.selection_method, value); + *usable_protocols &= OFPUTIL_P_OF15_UP; + } else if (!strcmp(name, "selection_method_param")) { + if (!(fields & F_GROUP_TYPE)) { + error = xstrdup("selection method param is not needed"); + goto out; + } + error = str_to_u64(value, &gm->props.selection_method_param); + *usable_protocols &= OFPUTIL_P_OF15_UP; + } else if (!strcmp(name, "fields")) { + if (!(fields & F_GROUP_TYPE)) { + error = xstrdup("fields are not needed"); + goto out; + } + error = parse_select_group_field(value, &gm->props.fields.flow, + &gm->props.fields.bm, + usable_protocols); + if (error) { + goto out; + } + *usable_protocols &= OFPUTIL_P_OF15_UP; } else { error = xasprintf("unknown keyword %s", name); goto out; diff --git a/tests/ofproto.at b/tests/ofproto.at index 8cfecc6..585d4cf 100644 --- a/tests/ofproto.at +++ b/tests/ofproto.at @@ -338,14 +338,14 @@ dnl Actions definition listed in both supported formats (w/ actions=) AT_SETUP([ofproto - del group (OpenFlow 1.5)]) OVS_VSWITCHD_START AT_DATA([groups.txt], [dnl -group_id=1234,type=all,bucket=output:10,bucket=output:11 +group_id=1234,type=select,selection_method=hash,bucket=output:10,bucket=output:11 group_id=1235,type=all,bucket=actions=output:12,bucket=bucket_id:0,actions=output:10,bucket=bucket_id:1,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:0,actions=output:10,bucket=bucket_id:1,actions=output:11 + group_id=1234,type=select,selection_method=hash,bucket=bucket_id:0,actions=output:10,bucket=bucket_id:1,actions=output:11 ]) AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn del-groups br0 group_id=1234]) AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn dump-groups br0], [0], [stdout]) diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in index 4641461..9522c55 100644 --- a/utilities/ovs-ofctl.8.in +++ b/utilities/ovs-ofctl.8.in @@ -1999,7 +1999,28 @@ 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 \fBselection_method\fR=\fImethod\fR +The selection method used to select a bucket for a select group. +This is a string of 1 to 15 bytes in length known to lower layers. +This field is optional for \fBadd\-group\fR, \fBadd\-groups\fR and +\fBmod\-group\fR commands on groups of type \fBselect\fR. Prohibited +otherwise. The default value is the empty string. +.IP \fBselection_method_param\fR=\fIparam\fR +64-bit integer parameter to the selection method selected by the +\fBselection_method\fR field. The parameter's use is defined by the +lower-layer that implements the \fBselection_method\fR. It is optional if +the \fBselection_method\fR field is specified as a non-empty string. +Prohibited otherwise. The default value is zero. +.IP \fBfields\fR=\fIparam\fR +The field parameters to selection method selected by the +\fBselection_method\fR field. The syntax is described in \fBFlow Syntax\fR +with the additional restriction that the if a value is provided it is +treated as a wildcard mask and wildcard masks following a slash are +prohibited. The pre-requisites of fields must be povided by any flows that +output to the group. The use of the fields is defined by the lower-layer +that implements the \fBselection_method\fR. They are optional if the +\fBselection_method\fR field is specified as a non-empty string. +Prohibited otherwise. The default is no fields. .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 -- 2.1.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev