Implement new OpenFlow "switch statistics" feature.
[openvswitch] / lib / ofp-print.c
index c8d8ad3198665e583384f405dd72b453f9524857..d758680f8f38ff6f2a31b011d6979a7097c1826f 100644 (file)
@@ -502,22 +502,28 @@ static void ofp_print_match(struct ds *f, const struct ofp_match *om,
     bool skip_type = false;
     bool skip_proto = false;
 
-    if (!(w & OFPFW_DL_TYPE) &&om->dl_type == htons(ETH_TYPE_IP)) {
+    if (!(w & OFPFW_DL_TYPE)) {
         skip_type = true;
-        if (!(w & OFPFW_NW_PROTO)) {
-            skip_proto = true;
-            if (om->nw_proto == IP_TYPE_ICMP) {
-                ds_put_cstr(f, "icmp,");
-            } else if (om->nw_proto == IP_TYPE_TCP) {
-                ds_put_cstr(f, "tcp,");
-            } else if (om->nw_proto == IP_TYPE_UDP) {
-                ds_put_cstr(f, "udp,");
+        if (om->dl_type == htons(ETH_TYPE_IP)) {
+            if (!(w & OFPFW_NW_PROTO)) {
+                skip_proto = true;
+                if (om->nw_proto == IP_TYPE_ICMP) {
+                    ds_put_cstr(f, "icmp,");
+                } else if (om->nw_proto == IP_TYPE_TCP) {
+                    ds_put_cstr(f, "tcp,");
+                } else if (om->nw_proto == IP_TYPE_UDP) {
+                    ds_put_cstr(f, "udp,");
+                } else {
+                    ds_put_cstr(f, "ip,");
+                    skip_proto = false;
+                }
             } else {
                 ds_put_cstr(f, "ip,");
-                skip_proto = false;
             }
+        } else if (om->dl_type == htons(ETH_TYPE_ARP)) {
+            ds_put_cstr(f, "arp,");
         } else {
-            ds_put_cstr(f, "ip,");
+            skip_type = false;
         }
     }
     print_wild(f, "in_port=", w & OFPFW_IN_PORT, verbosity,
@@ -809,6 +815,22 @@ ofp_table_stats_reply(struct ds *string, const void *body, size_t len,
      }
 }
 
+static void
+switch_status_reply(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);
+}
+
 enum stats_direction {
     REQUEST,
     REPLY
@@ -861,6 +883,11 @@ print_stats(struct ds *string, int type, const void *body, size_t body_len,
             { 0, 0, NULL, },
             { 0, SIZE_MAX, ofp_port_stats_reply },
         },
+        [OFPST_SWITCH] = {
+            "switch status",
+            { 0, 0, NULL, },
+            { 0, SIZE_MAX, switch_status_reply },
+        },
     };
 
     const struct stats_type *s;