Support printing of NMX selection method group experimenter property NMX selection method Signed-off-by: Simon Horman <simon.hor...@netronome.com> --- lib/flow.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ lib/flow.h | 2 ++ lib/ofp-print.c | 38 ++++++++++++++++++++++++++++++-------- tests/ofp-print.at | 16 ++++++++++++---- 4 files changed, 91 insertions(+), 12 deletions(-)
diff --git a/lib/flow.c b/lib/flow.c index 8c379f6..88794f0 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -31,6 +31,7 @@ #include "dynamic-string.h" #include "hash.h" #include "jhash.h" +#include "meta-flow.h" #include "match.h" #include "ofpbuf.h" #include "openflow/openflow.h" @@ -816,6 +817,52 @@ flow_print(FILE *stream, const struct flow *flow) fputs(s, stream); free(s); } + +/* Appends to 'b' the nx_match format that expresses the tlv with 'id' in + * 'mask'. 'mask' should contain mask values an only the name of a tlv + * is formated if its value is all ones. */ +static void +mask_format_tlv(struct ds *ds, const struct flow *mask, int id) +{ + const struct mf_field *mf = mf_from_id(id); + union mf_value value; + + mf_get_value(mf, mask, &value); + + ds_put_format(ds, "%s", mf->name); + + if (!is_all_ones(&value, mf->n_bytes)) { + ds_put_char(ds, '='); + mf_format(mf, &value, NULL, ds); + } + + ds_put_char(ds, ','); +} + +/* Appends a string representation of 'mask' to 's, + * formating each field whose corresponding bit is set in bm. + * 'mask' contains mask values and only the name of fields is + * formated if their value is all ones. */ +void +mask_format(struct ds *ds, const struct flow *mask, const struct mf_bitmap *bm) +{ + size_t start_len = ds->length; + int i; + + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 28); + + for (i = 0; i < MFF_N_IDS; i++) { + if (!bitmap_is_set(bm->bm, i)) { + continue; + } + + mask_format_tlv(ds, mask, i); + } + + if (ds->length > start_len) { + ds_chomp(ds, ','); + } +} /* flow_wildcards functions. */ diff --git a/lib/flow.h b/lib/flow.h index 2259680..ae955c3 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -34,6 +34,7 @@ struct flow_wildcards; struct minimask; struct ofpbuf; struct pkt_metadata; +struct mf_bitmap; /* This sequence number should be incremented whenever anything involving flows * or the wildcarding of flows changes. This will cause build assertion @@ -209,6 +210,7 @@ void format_flags_masked(struct ds *ds, const char *name, void flow_format(struct ds *, const struct flow *); void flow_print(FILE *, const struct flow *); +void mask_format(struct ds *ds, const struct flow *, const struct mf_bitmap *); static inline int flow_compare_3way(const struct flow *, const struct flow *); static inline bool flow_equal(const struct flow *, const struct flow *); static inline size_t flow_hash(const struct flow *, uint32_t basis); diff --git a/lib/ofp-print.c b/lib/ofp-print.c index c446770..c1d1e60 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -2139,8 +2139,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 list *p_buckets, enum ofp_version ofp_version, - bool suppress_type) + struct list *p_buckets, struct ofputil_group_props *props, + enum ofp_version ofp_version, bool suppress_type) { struct ofputil_bucket *bucket; @@ -2152,6 +2152,26 @@ 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; + mask_format(s, &props->fields.flow, &props->fields.bm); + if (s->length == start) { + ds_truncate(s, mark); + } + } + if (!p_buckets) { return; } @@ -2161,7 +2181,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); } @@ -2169,7 +2190,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="); @@ -2209,8 +2231,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_bucket_list_destroy(&gd.buckets); } } @@ -2363,8 +2385,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_bucket_list_destroy(&gm.buckets); } diff --git a/tests/ofp-print.at b/tests/ofp-print.at index 1221335..6148445 100644 --- a/tests/ofp-print.at +++ b/tests/ofp-print.at @@ -1979,7 +1979,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 \ @@ -1990,9 +1990,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 40 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 \ +00 01 00 17 80 00 18 04 ff ff ff 00 80 00 1a 02 \ +ff ff 80 00 14 01 ff 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,nw_proto,tcp_src,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 @@ -2798,7 +2803,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 c0 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 \ @@ -2807,9 +2812,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 30 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 00 01 00 04 00 00 00 00 \ "], [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.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev