Switch to new packet-out format and add OFPP_IN_PORT.
[sliver-openvswitch.git] / lib / ofp-print.c
index d1a8f8d..7e46999 100644 (file)
@@ -31,6 +31,7 @@
  * derivatives without specific, written prior permission.
  */
 
+#include <config.h>
 #include "ofp-print.h"
 #include "xtoxll.h"
 
@@ -185,6 +186,9 @@ static void ofp_print_port_name(struct ds *string, uint16_t port)
 {
     const char *name;
     switch (port) {
+    case OFPP_IN_PORT:
+        name = "IN_PORT";
+        break;
     case OFPP_TABLE:
         name = "TABLE";
         break;
@@ -256,11 +260,11 @@ ofp_print_action(struct ds *string, const struct ofp_action *a)
         break;
 
     case OFPAT_SET_NW_SRC:
-        ds_put_format(string, "mod_nw_src:"IP_FMT, IP_ARGS(a->arg.nw_addr));
+        ds_put_format(string, "mod_nw_src:"IP_FMT, IP_ARGS(&a->arg.nw_addr));
         break;
 
     case OFPAT_SET_NW_DST:
-        ds_put_format(string, "mod_nw_dst:"IP_FMT, IP_ARGS(a->arg.nw_addr));
+        ds_put_format(string, "mod_nw_dst:"IP_FMT, IP_ARGS(&a->arg.nw_addr));
         break;
 
     case OFPAT_SET_TP_SRC:
@@ -306,23 +310,31 @@ static void ofp_packet_out(struct ds *string, const void *oh, size_t len,
                            int verbosity) 
 {
     const struct ofp_packet_out *opo = oh;
+    int n_actions = ntohs(opo->n_actions);
+    int act_len = n_actions * sizeof opo->actions[0];
 
     ds_put_cstr(string, " in_port=");
     ofp_print_port_name(string, ntohs(opo->in_port));
 
+    ds_put_format(string, " n_actions=%d ", n_actions);
+    if (act_len > (ntohs(opo->header.length) - sizeof *opo)) {
+        ds_put_format(string, "***packet too short for number of actions***\n");
+        return;
+    }
+    ofp_print_actions(string, opo->actions, act_len);
+
     if (ntohl(opo->buffer_id) == UINT32_MAX) {
-        ds_put_cstr(string, " out_port=");
-        ofp_print_port_name(string, ntohs(opo->out_port));
+        int data_len = len - sizeof *opo - act_len;
+        ds_put_format(string, " data_len=%d", data_len);
         if (verbosity > 0 && len > sizeof *opo) {
-            char *packet = ofp_packet_to_string(opo->u.data, len - sizeof *opo,
-                                                len - sizeof *opo);
+            char *packet = ofp_packet_to_string(&opo->actions[n_actions], 
+                                                data_len, data_len);
             ds_put_char(string, '\n');
             ds_put_cstr(string, packet);
             free(packet);
         }
     } else {
         ds_put_format(string, " buffer=%08"PRIx32, ntohl(opo->buffer_id));
-        ofp_print_actions(string, opo->u.actions, len - sizeof *opo);
     }
     ds_put_char(string, '\n');
 }
@@ -434,6 +446,7 @@ static void print_wild(struct ds *string, const char *leader, int is_wild,
     } else {
         ds_put_char(string, '*');
     }
+    ds_put_char(string, ',');
 }
 
 /* Pretty-print the ofp_match structure */
@@ -443,25 +456,25 @@ static void ofp_print_match(struct ds *f, const struct ofp_match *om,
     uint16_t w = ntohs(om->wildcards);
 
     print_wild(f, "in_port=", w & OFPFW_IN_PORT, verbosity,
-               "%d,", ntohs(om->in_port));
+               "%d", ntohs(om->in_port));
     print_wild(f, "dl_vlan=", w & OFPFW_DL_VLAN, verbosity,
-               "%04x,", ntohs(om->dl_vlan));
+               "%04x", ntohs(om->dl_vlan));
     print_wild(f, "dl_src=", w & OFPFW_DL_SRC, verbosity,
-               ETH_ADDR_FMT",", ETH_ADDR_ARGS(om->dl_src));
+               ETH_ADDR_FMT, ETH_ADDR_ARGS(om->dl_src));
     print_wild(f, "dl_dst=", w & OFPFW_DL_DST, verbosity,
-               ETH_ADDR_FMT",", ETH_ADDR_ARGS(om->dl_dst));
+               ETH_ADDR_FMT, ETH_ADDR_ARGS(om->dl_dst));
     print_wild(f, "dl_type=", w & OFPFW_DL_TYPE, verbosity,
-               "%04x,", ntohs(om->dl_type));
+               "%04x", ntohs(om->dl_type));
     print_wild(f, "nw_src=", w & OFPFW_NW_SRC, verbosity,
-               IP_FMT",", IP_ARGS(&om->nw_src));
+               IP_FMT, IP_ARGS(&om->nw_src));
     print_wild(f, "nw_dst=", w & OFPFW_NW_DST, verbosity,
-               IP_FMT",", IP_ARGS(&om->nw_dst));
+               IP_FMT, IP_ARGS(&om->nw_dst));
     print_wild(f, "nw_proto=", w & OFPFW_NW_PROTO, verbosity,
-               "%u,", om->nw_proto);
+               "%u", om->nw_proto);
     print_wild(f, "tp_src=", w & OFPFW_TP_SRC, verbosity,
-               "%d,", ntohs(om->tp_src));
+               "%d", ntohs(om->tp_src));
     print_wild(f, "tp_dst=", w & OFPFW_TP_DST, verbosity,
-               "%d,", ntohs(om->tp_dst));
+               "%d", ntohs(om->tp_dst));
 }
 
 /* Pretty-print the OFPT_FLOW_MOD packet of 'len' bytes at 'oh' to 'string'
@@ -473,8 +486,9 @@ ofp_print_flow_mod(struct ds *string, const void *oh, size_t len,
     const struct ofp_flow_mod *ofm = oh;
 
     ofp_print_match(string, &ofm->match, verbosity);
-    ds_put_format(string, " cmd:%d idle:%d pri:%d buf:%#x", 
-            ntohs(ofm->command), ntohs(ofm->max_idle), 
+    ds_put_format(string, " cmd:%d idle:%d hard:%d pri:%d buf:%#x", 
+            ntohs(ofm->command), ntohs(ofm->idle_timeout),
+            ntohs(ofm->hard_timeout),
             ofm->match.wildcards ? ntohs(ofm->priority) : (uint16_t)-1,
             ntohl(ofm->buffer_id));
     ofp_print_actions(string, ofm->actions,
@@ -491,6 +505,18 @@ ofp_print_flow_expired(struct ds *string, const void *oh, size_t len,
     const struct ofp_flow_expired *ofe = oh;
 
     ofp_print_match(string, &ofe->match, verbosity);
+    ds_put_cstr(string, " reason=");
+    switch (ofe->reason) {
+    case OFPER_IDLE_TIMEOUT:
+        ds_put_cstr(string, "idle");
+        break;
+    case OFPER_HARD_TIMEOUT:
+        ds_put_cstr(string, "hard");
+        break;
+    default:
+        ds_put_format(string, "**%"PRIu8"**", ofe->reason);
+        break;
+    }
     ds_put_format(string, 
          " pri%"PRIu16" secs%"PRIu32" pkts%"PRIu64" bytes%"PRIu64"\n", 
          ofe->match.wildcards ? ntohs(ofe->priority) : (uint16_t)-1,
@@ -592,7 +618,10 @@ ofp_flow_stats_reply(struct ds *string, const void *body_, size_t len,
         ds_put_format(string, "n_packets=%"PRIu64", ",
                     ntohll(fs->packet_count));
         ds_put_format(string, "n_bytes=%"PRIu64", ", ntohll(fs->byte_count));
-        ds_put_format(string, "max_idle=%"PRIu16",", ntohs(fs->max_idle));
+        ds_put_format(string, "idle_timeout=%"PRIu16",",
+                      ntohs(fs->idle_timeout));
+        ds_put_format(string, "hard_timeout=%"PRIu16",",
+                      ntohs(fs->hard_timeout));
         ofp_print_match(string, &fs->match, verbosity);
         ofp_print_actions(string, fs->actions, length - sizeof *fs);
         ds_put_char(string, '\n');
@@ -780,6 +809,17 @@ ofp_stats_reply(struct ds *string, const void *oh, size_t len, int verbosity)
                 verbosity, REPLY);
 }
 
+static void
+ofp_echo(struct ds *string, const void *oh, size_t len, int verbosity)
+{
+    const struct ofp_header *hdr = oh;
+
+    ds_put_format(string, " %zu bytes of payload\n", len - sizeof *hdr);
+    if (verbosity > 1) {
+        ds_put_hex_dump(string, hdr, len - sizeof *hdr, 0, true); 
+    }
+}
+
 struct openflow_packet {
     const char *name;
     size_t min_size;
@@ -857,6 +897,16 @@ static const struct openflow_packet packets[] = {
         sizeof (struct ofp_stats_reply),
         ofp_stats_reply,
     },
+    [OFPT_ECHO_REQUEST] = {
+        "echo_request",
+        sizeof (struct ofp_header),
+        ofp_echo,
+    },
+    [OFPT_ECHO_REPLY] = {
+        "echo_reply",
+        sizeof (struct ofp_header),
+        ofp_echo,
+    },
 };
 
 /* Composes and returns a string representing the OpenFlow packet of 'len'