Include NMX selection method experimenter group property in in group mod request and group desc reply.
NMX selection method Signed-off-by: Simon Horman <simon.hor...@netronome.com> --- v2 Use list of struct field_array of TLVs rather than OF1.1 match for fields field of NMX selection method property --- lib/nx-match.c | 37 +++++++++++++++++++++++++++++++++++++ lib/nx-match.h | 2 ++ lib/ofp-util.c | 38 +++++++++++++++++++++++++++++++++++++- lib/ofp-util.h | 1 + ofproto/ofproto.c | 7 ++++++- 5 files changed, 83 insertions(+), 2 deletions(-) diff --git a/lib/nx-match.c b/lib/nx-match.c index 4f84619..82fcfc2 100644 --- a/lib/nx-match.c +++ b/lib/nx-match.c @@ -1068,6 +1068,43 @@ oxm_put_match(struct ofpbuf *b, const struct match *match, return match_len; } +/* Appends to 'b' a series of OXM TLVs corresponding to the series + * of enum mf_field_id and value tuples in 'fa_'. + * + * OXM differs slightly among versions of OpenFlow. Specify the OpenFlow + * version in use as 'version'. + * + * This function can cause 'b''s data to be reallocated. + * + * Returns the number of bytes appended to 'b'. May return zero. */ +int +oxm_put_field_array(struct ofpbuf *b, const struct ovs_list *field_array, + enum ofp_version version) +{ + size_t start_len = ofpbuf_size(b); + const struct field_array *fa; + + /* Field arrays are only used with the group selection method + * property and group properties are only available in OpenFlow * 1.5+. + * So the following assertion should never fail. + * + * If support for older OpenFlow versions is desired then some care + * will need to be taken of different TLVs that handle the same + * flow fields. In particular: + * - VLAN_TCI, VLAN_VID and MFF_VLAN_PCP + * - IP_DSCP_MASK and DSCP_SHIFTED + * - REGS and XREGS + */ + ovs_assert(version >= OFP15_VERSION); + + LIST_FOR_EACH (fa, list_node, field_array) { + nxm_put_unmasked(b, fa->id, version, &fa->value, + mf_from_id(fa->id)->n_bytes); + } + + return ofpbuf_size(b) - start_len; +} + static void nx_put_header__(struct ofpbuf *b, uint64_t header, bool masked) { diff --git a/lib/nx-match.h b/lib/nx-match.h index 1c9821c..14cd67a 100644 --- a/lib/nx-match.h +++ b/lib/nx-match.h @@ -61,6 +61,8 @@ enum ofperr oxm_pull_field_array(const void *, size_t fields_len, int nx_put_match(struct ofpbuf *, const struct match *, ovs_be64 cookie, ovs_be64 cookie_mask); int oxm_put_match(struct ofpbuf *, const struct match *, enum ofp_version); +int oxm_put_field_array(struct ofpbuf *, const struct ovs_list *, + enum ofp_version version); /* Decoding and encoding OXM/NXM headers (just a field ID) or entries (a field * ID followed by a value and possibly a mask). */ diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 9019a258..aa4af73 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -7423,6 +7423,27 @@ ofputil_put_ofp15_bucket(const struct ofputil_bucket *bucket, } static void +ofputil_put_group_prop_nmx_selection_method(enum ofp_version ofp_version, + const struct ofputil_group_props *gp, + const struct ovs_list *fields, + struct ofpbuf *openflow) +{ + struct nmx_group_prop_selection_method *prop; + size_t start; + + start = ofpbuf_size(openflow); + ofpbuf_put_zeros(openflow, sizeof *prop); + oxm_put_field_array(openflow, fields, ofp_version); + prop = ofpbuf_at_assert(openflow, start, sizeof *prop); + prop->type = htons(OFPGPT15_EXPERIMENTER); + prop->experimenter = htonl(NMX_VENDOR_ID); + prop->exp_type = htonl(NMXT_SELECTION_METHOD); + strcpy(prop->selection_method, gp->selection_method); + prop->selection_method_param = htonll(gp->selection_method_param); + end_property(openflow, start); +} + +static void ofputil_append_ofp11_group_desc_reply(const struct ofputil_group_desc *gds, const struct ovs_list *buckets, struct ovs_list *replies, @@ -7449,6 +7470,7 @@ ofputil_append_ofp11_group_desc_reply(const struct ofputil_group_desc *gds, static void ofputil_append_ofp15_group_desc_reply(const struct ofputil_group_desc *gds, const struct ovs_list *buckets, + const struct ovs_list *fields, struct ovs_list *replies, enum ofp_version version) { @@ -7470,6 +7492,12 @@ ofputil_append_ofp15_group_desc_reply(const struct ofputil_group_desc *gds, ogds->group_id = htonl(gds->group_id); ogds->bucket_list_len = htons(ofpbuf_size(reply) - start_buckets); + /* Add group properties */ + if (gds->props.selection_method[0]) { + ofputil_put_group_prop_nmx_selection_method(version, &gds->props, + fields, reply); + } + ofpmp_postappend(replies, start_ogds); } @@ -7479,6 +7507,7 @@ ofputil_append_ofp15_group_desc_reply(const struct ofputil_group_desc *gds, void ofputil_append_group_desc_reply(const struct ofputil_group_desc *gds, const struct ovs_list *buckets, + const struct ovs_list *fields, struct ovs_list *replies) { enum ofp_version version = ofpmp_version(replies); @@ -7493,7 +7522,8 @@ ofputil_append_group_desc_reply(const struct ofputil_group_desc *gds, break; case OFP15_VERSION: - ofputil_append_ofp15_group_desc_reply(gds, buckets, replies, version); + ofputil_append_ofp15_group_desc_reply(gds, buckets, fields, replies, + version); break; case OFP10_VERSION: @@ -8126,6 +8156,12 @@ ofputil_encode_ofp15_group_mod(enum ofp_version ofp_version, ogm->command_bucket_id = htonl(gm->command_bucket_id); ogm->bucket_array_len = htons(ofpbuf_size(b) - start_ogm - sizeof *ogm); + /* Add group properties */ + if (gm->props.selection_method[0]) { + ofputil_put_group_prop_nmx_selection_method(ofp_version, &gm->props, + &gm->props.fields, b); + } + id_pool_destroy(bucket_ids); return b; } diff --git a/lib/ofp-util.h b/lib/ofp-util.h index 31b250b..f75c363 100644 --- a/lib/ofp-util.h +++ b/lib/ofp-util.h @@ -1095,6 +1095,7 @@ int ofputil_decode_group_desc_reply(struct ofputil_group_desc *, void ofputil_append_group_desc_reply(const struct ofputil_group_desc *, const struct ovs_list *buckets, + const struct ovs_list *fields, struct ovs_list *replies); struct ofputil_bundle_ctrl_msg { diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 2f4d62f..b0043b0 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -5749,7 +5749,12 @@ append_group_desc(struct ofgroup *group, struct ovs_list *replies) gds.group_id = group->group_id; gds.type = group->type; - ofputil_append_group_desc_reply(&gds, &group->buckets, replies); + + memcpy(gds.props.selection_method, group->selection_method, + NMX_MAX_SELECTION_METHOD_LEN); + gds.props.selection_method_param = group->selection_method_param; + ofputil_append_group_desc_reply(&gds, &group->buckets, + &group->fields, replies); } static enum ofperr -- 2.1.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev