Merge branch "partner", to simplify partner integration.
[sliver-openvswitch.git] / lib / ofp-print.c
index 6f0957a..e78a24a 100644 (file)
@@ -411,11 +411,8 @@ ofp_print_switch_features(struct ds *string, const void *oh, size_t len,
     int i;
 
     ds_put_format(string, "dp id:%"PRIx64"\n", ntohll(osf->datapath_id));
-    ds_put_format(string, "tables: exact:%d, compressed:%d, general:%d\n",
-           ntohl(osf->n_exact), 
-           ntohl(osf->n_compression), ntohl(osf->n_general));
-    ds_put_format(string, "buffers: size:%d, number:%d\n",
-           ntohl(osf->buffer_mb), ntohl(osf->n_buffers));
+    ds_put_format(string, "n_tables:%d, n_buffers:%d\n", osf->n_tables,
+            ntohl(osf->n_buffers));
     ds_put_format(string, "features: capabilities:%#x, actions:%#x\n",
            ntohl(osf->capabilities), ntohl(osf->actions));
 
@@ -599,16 +596,82 @@ ofp_print_flow_expired(struct ds *string, const void *oh, size_t len,
          ntohll(ofe->byte_count));
 }
 
-/* Pretty-print the OFPT_ERROR_MSG packet of 'len' bytes at 'oh' to 'string'
+struct error_type {
+    int type;
+    int code;
+    const char *name;
+};
+
+static const struct error_type error_types[] = {
+#define ERROR_TYPE(TYPE) {TYPE, -1, #TYPE}
+#define ERROR_CODE(TYPE, CODE) {TYPE, CODE, #CODE}
+    ERROR_TYPE(OFPET_HELLO_FAILED),
+    ERROR_CODE(OFPET_HELLO_FAILED, OFPHFC_INCOMPATIBLE),
+
+    ERROR_TYPE(OFPET_BAD_REQUEST),
+    ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION),
+    ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE),
+    ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_STAT),
+    ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION),
+};
+#define N_ERROR_TYPES ARRAY_SIZE(error_types)
+
+static const char *
+lookup_error_type(int type)
+{
+    const struct error_type *t;
+
+    for (t = error_types; t < &error_types[N_ERROR_TYPES]; t++) {
+        if (t->type == type && t->code == -1) {
+            return t->name;
+        }
+    }
+    return "?";
+}
+
+static const char *
+lookup_error_code(int type, int code)
+{
+    const struct error_type *t;
+
+    for (t = error_types; t < &error_types[N_ERROR_TYPES]; t++) {
+        if (t->type == type && t->code == code) {
+            return t->name;
+        }
+    }
+    return "?";
+}
+
+/* Pretty-print the OFPT_ERROR packet of 'len' bytes at 'oh' to 'string'
  * at the given 'verbosity' level. */
 static void
 ofp_print_error_msg(struct ds *string, const void *oh, size_t len, 
                        int verbosity)
 {
     const struct ofp_error_msg *oem = oh;
+    int type = ntohs(oem->type);
+    int code = ntohs(oem->code);
+    char *s;
 
-    ds_put_format(string, 
-         " type%d code%d\n", ntohs(oem->type), ntohs(oem->code));
+    ds_put_format(string, " type%d(%s) code%d(%s) payload:\n",
+                  type, lookup_error_type(type),
+                  code, lookup_error_code(type, code));
+
+    switch (type) {
+    case OFPET_HELLO_FAILED:
+        ds_put_printable(string, (char *) oem->data, len - sizeof *oem);
+        break;
+
+    case OFPET_BAD_REQUEST:
+        s = ofp_to_string(oem->data, len - sizeof *oem, 1);
+        ds_put_cstr(string, s);
+        free(s);
+        break;
+
+    default:
+        ds_put_hex_dump(string, oem->data, len - sizeof *oem, 0, true);
+        break;
+    }
 }
 
 /* Pretty-print the OFPT_PORT_STATUS packet of 'len' bytes at 'oh' to 'string'
@@ -807,29 +870,22 @@ ofp_table_stats_reply(struct ds *string, const void *body, size_t len,
         strncpy(name, ts->name, sizeof name);
         name[OFP_MAX_TABLE_NAME_LEN] = '\0';
 
-        ds_put_format(string, "  table %"PRIu8": ", ts->table_id);
-        ds_put_format(string, "name %-8s, ", name);
-        ds_put_format(string, "max %6"PRIu32", ", ntohl(ts->max_entries));
-        ds_put_format(string, "active %6"PRIu32", ", ntohl(ts->active_count));
-        ds_put_format(string, "matched %6"PRIu64"\n",
+        ds_put_format(string, "  %d: %-8s: ", ts->table_id, name);
+        ds_put_format(string, "wild=0x%05"PRIx32", ", ntohl(ts->wildcards));
+        ds_put_format(string, "max=%6"PRIu32", ", ntohl(ts->max_entries));
+        ds_put_format(string, "active=%6"PRIu32", ", ntohl(ts->active_count));
+        ds_put_format(string, "matched=%6"PRIu64"\n",
                       ntohll(ts->matched_count));
      }
 }
 
 static void
-switch_status_reply(struct ds *string, const void *body, size_t len,
-                    int verbosity UNUSED)
+vendor_stat(struct ds *string, const void *body, size_t len,
+            int verbosity UNUSED)
 {
-    char *save_ptr = NULL;
-    char *s, *line;
-
-    s = xmemdup0(body, len);
-    for (line = strtok_r(s, "\n\n", &save_ptr); line != NULL;
-         line = strtok_r(NULL, "\n\n", &save_ptr)) {
-        ds_put_printable(string, line, strlen(line));
-        ds_put_char(string, '\n');
-    }
-    free(s);
+    ds_put_format(string, " vendor=%08"PRIx32, ntohl(*(uint32_t *) body));
+    ds_put_format(string, " %zu bytes additional data",
+                  len - sizeof(uint32_t));
 }
 
 enum stats_direction {
@@ -891,10 +947,10 @@ print_stats(struct ds *string, int type, const void *body, size_t body_len,
             { 0, SIZE_MAX, ofp_port_stats_reply },
         },
         {
-            OFPST_SWITCH,
-            "switch status",
-            { 0, 0, NULL, },
-            { 0, SIZE_MAX, switch_status_reply },
+            OFPST_VENDOR,
+            "vendor-specific",
+            { sizeof(uint32_t), SIZE_MAX, vendor_stat },
+            { sizeof(uint32_t), SIZE_MAX, vendor_stat },
         },
         {
             -1,
@@ -987,6 +1043,12 @@ struct openflow_packet {
 };
 
 static const struct openflow_packet packets[] = {
+    {
+        OFPT_HELLO,
+        "hello",
+        sizeof (struct ofp_header),
+        NULL,
+    },
     {
         OFPT_FEATURES_REQUEST,
         "features_request",
@@ -1054,7 +1116,7 @@ static const struct openflow_packet packets[] = {
         ofp_print_port_status
     },
     {
-        OFPT_ERROR_MSG,
+        OFPT_ERROR,
         "error_msg",
         sizeof (struct ofp_error_msg),
         ofp_print_error_msg,