Support printing of NMX selection method group experimenter property
NMX selection method
Signed-off-by: Simon Horman <[email protected]>
---
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 | 41 +++++++++++++++++++++++++++++++++++++++++
lib/nx-match.h | 1 +
lib/ofp-print.c | 40 ++++++++++++++++++++++++++++++++--------
tests/ofp-print.at | 16 ++++++++++++----
4 files changed, 86 insertions(+), 12 deletions(-)
diff --git a/lib/nx-match.c b/lib/nx-match.c
index 82fcfc2..a9b9dfd 100644
--- a/lib/nx-match.c
+++ b/lib/nx-match.c
@@ -1068,6 +1068,47 @@ oxm_put_match(struct ofpbuf *b, const struct match
*match,
return match_len;
}
+/* Appends to 'b' the nx_match format that expresses the tlv corresponding
+ * to 'id'. If mask is not all-ones then it is also formated as the value
+ * of the tlv. */
+static void
+nx_format_mask_tlv(struct ds *ds, enum mf_field_id id,
+ const union mf_value *mask)
+{
+ const struct mf_field *mf = mf_from_id(id);
+
+ ds_put_format(ds, "%s", mf->name);
+
+ if (!is_all_ones(mask, mf->n_bytes)) {
+ ds_put_char(ds, '=');
+ mf_format(mf, mask, NULL, ds);
+ }
+
+ ds_put_char(ds, ',');
+}
+
+/* Appends a string representation of 'fa_' to 'ds'.
+ * The TLVS value of 'fa_' is treated as a mask and
+ * only the name of fields is formated if it is all ones.
+ *
+ * Returns 0 on success, an ofperr value otherwise */
+int
+oxm_format_field_array(struct ds *ds, const struct ovs_list *field_array)
+{
+ size_t start_len = ds->length;
+ const struct field_array *fa;
+
+ LIST_FOR_EACH (fa, list_node, field_array) {
+ nx_format_mask_tlv(ds, fa->id, &fa->value);
+ }
+
+ if (ds->length > start_len) {
+ ds_chomp(ds, ',');
+ }
+
+ return 0;
+}
+
/* Appends to 'b' a series of OXM TLVs corresponding to the series
* of enum mf_field_id and value tuples in 'fa_'.
*
diff --git a/lib/nx-match.h b/lib/nx-match.h
index 14cd67a..1764aee 100644
--- a/lib/nx-match.h
+++ b/lib/nx-match.h
@@ -61,6 +61,7 @@ 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_format_field_array(struct ds *, const struct ovs_list *);
int oxm_put_field_array(struct ofpbuf *, const struct ovs_list *,
enum ofp_version version);
diff --git a/lib/ofp-print.c b/lib/ofp-print.c
index a596979..c3a6d07 100644
--- a/lib/ofp-print.c
+++ b/lib/ofp-print.c
@@ -2147,8 +2147,8 @@ ofp_print_bucket_id(struct ds *s, const char *label,
uint32_t bucket_id,
static void
ofp_print_group(struct ds *s, uint32_t group_id, uint8_t type,
- struct ovs_list *p_buckets, enum ofp_version ofp_version,
- bool suppress_type)
+ struct ovs_list *p_buckets, struct ofputil_group_props *props,
+ enum ofp_version ofp_version, bool suppress_type)
{
struct ofputil_bucket *bucket;
@@ -2160,6 +2160,28 @@ ofp_print_group(struct ds *s, uint32_t group_id, uint8_t
type,
ds_put_format(s, ",type=%s", type_str[type > 4 ? 4 : type]);
}
+ if (props->selection_method[0]) {
+ size_t mark, start;
+
+ ds_put_format(s, ",selection_method=%s,", props->selection_method);
+ if (props->selection_method_param) {
+ ds_put_format(s, "selection_method_param=%"PRIu64",",
+ props->selection_method_param);
+ }
+
+ /* Allow rewinding to immediately before the trailing ',' */
+ mark = s->length - 1;
+
+ ds_put_cstr(s, "fields=");
+ start = s->length;
+ if (oxm_format_field_array(s, &props->fields)) {
+ ds_put_cstr(s, " ***formatting error***");
+ }
+ if (s->length == start) {
+ ds_truncate(s, mark);
+ }
+ }
+
if (!p_buckets) {
return;
}
@@ -2169,7 +2191,8 @@ ofp_print_group(struct ds *s, uint32_t group_id, uint8_t
type,
LIST_FOR_EACH (bucket, list_node, p_buckets) {
ds_put_cstr(s, "bucket=");
- ofp_print_bucket_id(s, "bucket_id:", bucket->bucket_id, ofp_version);
+ ofp_print_bucket_id(s, "bucket_id:", bucket->bucket_id,
+ ofp_version);
if (bucket->weight != 1) {
ds_put_format(s, "weight:%"PRIu16",", bucket->weight);
}
@@ -2177,7 +2200,8 @@ ofp_print_group(struct ds *s, uint32_t group_id, uint8_t
type,
ds_put_format(s, "watch_port:%"PRIu32",", bucket->watch_port);
}
if (bucket->watch_group != OFPG11_ANY) {
- ds_put_format(s, "watch_group:%"PRIu32",", bucket->watch_group);
+ ds_put_format(s, "watch_group:%"PRIu32",",
+ bucket->watch_group);
}
ds_put_cstr(s, "actions=");
@@ -2217,8 +2241,8 @@ ofp_print_group_desc(struct ds *s, const struct
ofp_header *oh)
ds_put_char(s, '\n');
ds_put_char(s, ' ');
- ofp_print_group(s, gd.group_id, gd.type, &gd.buckets, oh->version,
- false);
+ ofp_print_group(s, gd.group_id, gd.type, &gd.buckets, &gd.props,
+ oh->version, false);
ofputil_uninit_group_desc(&gd);
}
}
@@ -2371,8 +2395,8 @@ ofp_print_group_mod(struct ds *s, const struct ofp_header
*oh)
gm.command_bucket_id, oh->version);
}
- ofp_print_group(s, gm.group_id, gm.type, &gm.buckets, oh->version,
- bucket_command);
+ ofp_print_group(s, gm.group_id, gm.type, &gm.buckets, &gm.props,
+ oh->version, bucket_command);
ofputil_uninit_group_mod(&gm);
}
diff --git a/tests/ofp-print.at b/tests/ofp-print.at
index dc809e2..3978f65 100644
--- a/tests/ofp-print.at
+++ b/tests/ofp-print.at
@@ -2026,7 +2026,7 @@ AT_CLEANUP
AT_SETUP([OFPST_GROUP_DESC reply - OF1.5])
AT_KEYWORDS([ofp-print OFPT_STATS_REPLY])
AT_CHECK([ovs-ofctl ofp-print "\
-06 13 00 98 00 00 00 02 00 07 00 00 00 00 00 00 \
+06 13 00 d8 00 00 00 02 00 07 00 00 00 00 00 00 \
00 88 01 00 00 00 20 00 00 78 00 00 00 00 00 00 \
00 28 00 10 00 00 00 00 00 00 00 10 00 00 00 01 \
00 00 00 00 00 00 00 00 00 00 00 08 00 64 00 00 \
@@ -2037,9 +2037,14 @@ AT_CHECK([ovs-ofctl ofp-print "\
00 28 00 10 00 00 00 02 00 00 00 10 00 00 00 03 \
00 00 00 00 00 00 00 00 00 00 00 08 00 c8 00 00 \
00 01 00 08 00 00 00 03 \
+ff ff 00 3b 00 00 15 40 00 00 00 01 00 00 00 00 \
+68 61 73 68 00 00 00 00 00 00 00 00 00 00 00 00 \
+00 00 00 00 00 00 00 00 \
+80 00 18 04 ff ff ff 00 80 00 1a 02 ff ff 80 00 \
+14 01 ff 00 00 00 00 00 \
"], [0], [dnl
OFPST_GROUP_DESC reply (OF1.5) (xid=0x2):
-
group_id=8192,type=select,bucket=bucket_id:0,weight:100,watch_port:1,actions=output:1,bucket=bucket_id:1,weight:200,watch_port:2,actions=output:2,bucket=bucket_id:2,weight:200,watch_port:3,actions=output:3
+
group_id=8192,type=select,selection_method=hash,fields=ip_dst=255.255.255.0,tcp_src,nw_proto,bucket=bucket_id:0,weight:100,watch_port:1,actions=output:1,bucket=bucket_id:1,weight:200,watch_port:2,actions=output:2,bucket=bucket_id:2,weight:200,watch_port:3,actions=output:3
])
AT_CLEANUP
@@ -2845,7 +2850,7 @@ AT_CLEANUP
AT_SETUP([OFPT_GROUP_MOD add - OF1.5])
AT_KEYWORDS([ofp-print])
AT_CHECK([ovs-ofctl ofp-print "\
-06 0f 00 90 11 22 33 44 00 00 01 00 87 65 43 21 \
+06 0f 00 b8 11 22 33 44 00 00 01 00 87 65 43 21 \
00 78 00 00 ff ff ff ff 00 28 00 10 00 00 00 00 \
00 00 00 10 00 00 00 01 00 00 00 00 00 00 00 00 \
00 00 00 08 00 64 00 00 00 01 00 08 00 00 00 01 \
@@ -2854,9 +2859,12 @@ AT_CHECK([ovs-ofctl ofp-print "\
00 01 00 08 00 00 00 02 00 28 00 10 00 00 00 02 \
00 00 00 10 00 00 00 03 00 00 00 00 00 00 00 00 \
00 00 00 08 00 c8 00 00 00 01 00 08 00 00 00 03 \
+ff ff 00 28 00 00 15 40 00 00 00 01 00 00 00 00 \
+72 61 6e 64 6f 6d 00 00 00 00 00 00 00 00 00 00 \
+00 00 00 00 00 00 00 07 \
"], [0], [dnl
OFPT_GROUP_MOD (OF1.5) (xid=0x11223344):
- ADD
group_id=2271560481,type=select,bucket=bucket_id:0,weight:100,watch_port:1,actions=output:1,bucket=bucket_id:1,weight:200,watch_port:2,actions=output:2,bucket=bucket_id:2,weight:200,watch_port:3,actions=output:3
+ ADD
group_id=2271560481,type=select,selection_method=random,selection_method_param=7,bucket=bucket_id:0,weight:100,watch_port:1,actions=output:1,bucket=bucket_id:1,weight:200,watch_port:2,actions=output:2,bucket=bucket_id:2,weight:200,watch_port:3,actions=output:3
])
AT_CLEANUP
--
2.1.4
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev