[ovs-dev] [PATCH 5/9] ofp-print: Implement the function to print OFPMP_TABLE_FEATURES

Alexander Wu alexander.wu at huawei.com
Thu Nov 21 09:04:32 UTC 2013


V3:
  Modify type of element_size and print error if 0.
  Fix CodingStyle.
  Change print of next_tables msg, change enums to OFPUTIL_*.
  Make all print human-readable.

V2:
  Change calls from ofputil.
  Fix CodingStyle accoring to Simon Horman's suggestions.

V1:
  Add function to print OFPMP_TABLE_FEATURES.
  But now the print is crude and dirty.
  Fix it to bitmap or more desc later.

Signed-off-by: Alexander Wu <alexander.wu at huawei.com>
---
 lib/ofp-print.c |  140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 139 insertions(+), 1 deletions(-)

diff --git a/lib/ofp-print.c b/lib/ofp-print.c
index 37e1f4f..60a7470 100644
--- a/lib/ofp-print.c
+++ b/lib/ofp-print.c
@@ -2485,6 +2485,144 @@ ofp_print_group_mod(struct ds *s, const struct ofp_header *oh)
     ofp_print_group(s, gm.group_id, gm.type, &gm.buckets);
 }
 
+/* Appends a string representation of 'prop' to 's'. */
+static void
+table_feature_prop_format(const struct ofputil_table_feature_prop_header *prop,
+                          struct ds *s)
+{
+    int i = 0;
+    int n = 0;
+    uint16_t element_size = table_feature_prop_get_length(prop->type);
+
+    if (!element_size) {
+        ofp_print_error(s, OFPERR_OFPTFFC_BAD_LEN);
+        return;
+    } else {
+        n = (prop->length - 4) / element_size;
+    }
+
+    ds_put_format(s, "%s: ", table_feature_prop_get_name(prop->type));
+
+    switch (prop->type) {
+    case OFPUTIL_INSTRUCTIONS:
+    case OFPUTIL_INSTRUCTIONS_MISS: {
+        struct ofp11_instruction *inst = (struct ofp11_instruction *)prop->data;
+
+        for (i = 0; i < n; i++) {
+            ds_put_format(s, "%s", ovs_instruction_name_from_type(
+                ovs_instruction_type_from_inst_type(inst[i].type)));
+
+            if (i != n - 1) {
+                ds_put_format(s, ",");
+            }
+        }
+        break;
+    }
+    case OFPUTIL_NEXT_TABLES:
+    case OFPUTIL_NEXT_TABLES_MISS: {
+
+        /* Currently we're sure the table is continuous. So it's enough to
+         * print the start and end of the next tables only. */
+        uint8_t *ntables = prop->data;
+        if (n > 1) {
+            ds_put_format(s, "%"PRIu8" to ", ntables[0]);
+        }
+        ds_put_format(s, "%"PRIu8, ntables[n - 1]);
+        break;
+    }
+    case OFPUTIL_WRITE_ACTIONS:
+    case OFPUTIL_WRITE_ACTIONS_MISS:
+    case OFPUTIL_APPLY_ACTIONS:
+    case OFPUTIL_APPLY_ACTIONS_MISS: {
+        struct ofp_action_header *acts =(struct ofp_action_header *)prop->data;
+        char *name;
+
+        for (i = 0; i < n; i++) {
+            name = get_action_name(acts[i].type);
+            if (!name) {
+                ds_put_format(s, "Unknown action(%"PRIu16")", acts[i].type);
+            } else {
+                ds_put_format(s, "%s", name);
+            }
+            if (i != n - 1) {
+                ds_put_format(s, ",");
+            }
+        }
+        break;
+    }
+    case OFPUTIL_MATCH:
+    case OFPUTIL_WILDCARDS:
+    case OFPUTIL_WRITE_SETFIELD:
+    case OFPUTIL_WRITE_SETFIELD_MISS:
+    case OFPUTIL_APPLY_SETFIELD:
+    case OFPUTIL_APPLY_SETFIELD_MISS: {
+        uint32_t *oxm = (uint32_t *)prop->data;
+
+        for (i = 0; i < n; i++) {
+            ds_put_format(s, "%s", get_oxm_name(oxm[i]));
+            if ((oxm[i] >> 8) & 1) {
+                ds_put_format(s, ":1");
+            }
+
+            if (i != n - 1) {
+                ds_put_format(s, ",");
+            }
+        }
+        break;
+    }
+    case OFPUTIL_EXPERIMENTER:
+    case OFPUTIL_EXPERIMENTER_MISS:
+        ds_put_format(s, "experimenter");
+        if (i != n - 1)
+            ds_put_format(s, ",");
+        break;
+    default:
+        ds_put_format(s, "unknown(%u)", prop->type);
+        break;
+    }
+}
+
+
+static void
+ofp_print_table_features_stats_single(struct ds *s,
+                                      const struct ofputil_table_features *tf)
+{
+    int i;
+    ds_put_format(s, "\n  %"PRIu8":", tf->table_id);
+    ds_put_format(s, " name:%s", tf->name);
+    ds_put_format(s, " metadata_match:%"PRIx64, tf->metadata_match);
+    ds_put_format(s, " metadata_write:%"PRIx64, tf->metadata_write);
+    ds_put_format(s, " config:%"PRIx32, tf->config);
+    ds_put_format(s, " max_entries:%"PRIu32, tf->max_entries);
+
+    ds_put_format(s, "\n    Properties:");
+    for (i = 0; i < tf->n_property; i++) {
+        if (tf->props[i].data == NULL || tf->props[i].length == 0)
+            continue;
+
+        ds_put_format(s, "\n      ");
+        table_feature_prop_format(&tf->props[i], s);
+    }
+    ds_put_format(s, "\n");
+}
+
+static void
+ofp_print_table_features_stats(struct ds *s, const struct ofp_header *oh)
+{
+    struct ofputil_table_features tfs[OFTABLE_NUM];
+    int tfs_num;
+    int i;
+    int error;
+    uint32_t flag;
+
+    memset(tfs, 0, sizeof(tfs));
+    error = ofputil_pull_table_features(oh, &tfs_num, tfs, &flag);
+
+    for (i = 0; i < tfs_num; i++) {
+        ofp_print_table_features_stats_single(s, &tfs[i]);
+    }
+}
+
 static void
 ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw,
                 struct ds *string, int verbosity)
@@ -2525,7 +2663,7 @@ ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw,
 
     case OFPTYPE_TABLE_FEATURES_STATS_REQUEST:
     case OFPTYPE_TABLE_FEATURES_STATS_REPLY:
-        ofp_print_not_implemented(string);
+        ofp_print_table_features_stats(string, oh);
         break;
 
     case OFPTYPE_HELLO:
-- 
1.7.3.1.msysgit.0





More information about the dev mailing list