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

Reply via email to