uuid: Correct name of header file in comment.
[sliver-openvswitch.git] / lib / ofp-print.c
index 5370c9a..d88a574 100644 (file)
@@ -30,6 +30,7 @@
 #include "compiler.h"
 #include "dynamic-string.h"
 #include "flow.h"
+#include "multipath.h"
 #include "nx-match.h"
 #include "ofp-util.h"
 #include "ofpbuf.h"
@@ -215,6 +216,8 @@ nx_action_len(enum nx_action_subtype subtype)
     case NXAST_REG_MOVE: return sizeof(struct nx_action_reg_move);
     case NXAST_REG_LOAD: return sizeof(struct nx_action_reg_load);
     case NXAST_NOTE: return -1;
+    case NXAST_SET_TUNNEL64: return sizeof(struct nx_action_set_tunnel64);
+    case NXAST_MULTIPATH: return sizeof(struct nx_action_multipath);
     default: return -1;
     }
 }
@@ -233,11 +236,13 @@ ofp_print_nx_action(struct ds *string, const struct nx_action_header *nah)
     }
 
     if (subtype <= TYPE_MAXIMUM(enum nx_action_subtype)) {
+        const struct nx_action_set_tunnel64 *nast64;
         const struct nx_action_set_tunnel *nast;
         const struct nx_action_set_queue *nasq;
         const struct nx_action_resubmit *nar;
         const struct nx_action_reg_move *move;
         const struct nx_action_reg_load *load;
+        const struct nx_action_multipath *nam;
 
         switch ((enum nx_action_subtype) subtype) {
         case NXAST_RESUBMIT:
@@ -278,6 +283,17 @@ ofp_print_nx_action(struct ds *string, const struct nx_action_header *nah)
             nxm_format_reg_load(load, string);
             return;
 
+        case NXAST_SET_TUNNEL64:
+            nast64 = (const struct nx_action_set_tunnel64 *) nah;
+            ds_put_format(string, "set_tunnel64:%#"PRIx64,
+                          ntohll(nast64->tun_id));
+            return;
+
+        case NXAST_MULTIPATH:
+            nam = (const struct nx_action_multipath *) nah;
+            multipath_format(nam, string);
+            return;
+
         case NXAST_SNAT__OBSOLETE:
         default:
             break;
@@ -790,6 +806,7 @@ ofp_print_flow_mod(struct ds *s, const struct ofp_header *oh,
                    enum ofputil_msg_code code, int verbosity)
 {
     struct flow_mod fm;
+    bool need_priority;
     int error;
 
     error = ofputil_decode_flow_mod(&fm, oh, NXFF_OPENFLOW10);
@@ -822,16 +839,26 @@ ofp_print_flow_mod(struct ds *s, const struct ofp_header *oh,
     ds_put_char(s, ' ');
     if (verbosity >= 3 && code == OFPUTIL_OFPT_FLOW_MOD) {
         const struct ofp_flow_mod *ofm = (const struct ofp_flow_mod *) oh;
-
         ofp_print_match(s, &ofm->match, verbosity);
+
+        /* ofp_print_match() doesn't print priority. */
+        need_priority = true;
     } else if (verbosity >= 3 && code == OFPUTIL_NXT_FLOW_MOD) {
         const struct nx_flow_mod *nfm = (const struct nx_flow_mod *) oh;
         const void *nxm = nfm + 1;
-        char *nxm_s = nx_match_to_string(nxm, ntohs(nfm->match_len));
+        char *nxm_s;
+
+        nxm_s = nx_match_to_string(nxm, ntohs(nfm->match_len));
         ds_put_cstr(s, nxm_s);
         free(nxm_s);
+
+        /* nx_match_to_string() doesn't print priority. */
+        need_priority = true;
     } else {
         cls_rule_format(&fm.cr, s);
+
+        /* cls_rule_format() does print priority. */
+        need_priority = false;
     }
 
     if (ds_last(s) != ' ') {
@@ -846,7 +873,7 @@ ofp_print_flow_mod(struct ds *s, const struct ofp_header *oh,
     if (fm.hard_timeout != OFP_FLOW_PERMANENT) {
         ds_put_format(s, "hard:%"PRIu16" ", fm.hard_timeout);
     }
-    if (fm.cr.priority != OFP_DEFAULT_PRIORITY && verbosity >= 3) {
+    if (fm.cr.priority != OFP_DEFAULT_PRIORITY && need_priority) {
         ds_put_format(s, "pri:%"PRIu16" ", fm.cr.priority);
     }
     if (fm.buffer_id != UINT32_MAX) {
@@ -1017,7 +1044,7 @@ ofp_print_error(struct ds *string, int error)
     if (string->length) {
         ds_put_char(string, ' ');
     }
-    ds_put_format(string, " ***decode error type:%d(%s) code:%d(%s)***",
+    ds_put_format(string, " ***decode error type:%d(%s) code:%d(%s)***\n",
                   type, lookup_error_type(type),
                   code, lookup_error_code(type, code));
 }
@@ -1248,7 +1275,6 @@ ofp_print_nxst_flow_reply(struct ds *string, const struct ofp_header *oh)
         ofp_print_duration(string, ntohl(fs->duration_sec),
                            ntohl(fs->duration_nsec));
         ds_put_format(string, ", table_id=%"PRIu8", ", fs->table_id);
-        ds_put_format(string, "priority=%"PRIu16", ", ntohs(fs->priority));
         ds_put_format(string, "n_packets=%"PRIu64", ",
                     ntohll(fs->packet_count));
         ds_put_format(string, "n_bytes=%"PRIu64", ", ntohll(fs->byte_count));
@@ -1702,14 +1728,17 @@ ofp_to_string(const void *oh_, size_t len, int verbosity)
     struct ds string = DS_EMPTY_INITIALIZER;
     const struct ofp_header *oh = oh_;
 
-    if (len < sizeof(struct ofp_header)) {
-        ds_put_cstr(&string, "OpenFlow packet too short:\n");
+    if (!len) {
+        ds_put_cstr(&string, "OpenFlow message is empty\n");
+    } else if (len < sizeof(struct ofp_header)) {
+        ds_put_format(&string, "OpenFlow packet too short (only %zu bytes):\n",
+                      len);
     } else if (oh->version != OFP_VERSION) {
         ds_put_format(&string, "Bad OpenFlow version %"PRIu8":\n",
                       oh->version);
     } else if (ntohs(oh->length) > len) {
         ds_put_format(&string,
-                      "(***truncated to %zu bytes from %"PRIu16"***)",
+                      "(***truncated to %zu bytes from %"PRIu16"***)\n",
                       len, ntohs(oh->length));
     } else if (ntohs(oh->length) < len) {
         ds_put_format(&string,