ofp-util: Don't return static data in ofputil_packet_in_reason_to_string().
[sliver-openvswitch.git] / lib / ofp-print.c
index f45ffa4..9471385 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -44,7 +44,6 @@
 #include "openflow/openflow.h"
 #include "openflow/nicira-ext.h"
 #include "packets.h"
-#include "pcap.h"
 #include "type-props.h"
 #include "unaligned.h"
 #include "util.h"
@@ -87,6 +86,7 @@ static void
 ofp_print_packet_in(struct ds *string, const struct ofp_header *oh,
                     int verbosity)
 {
+    char reasonbuf[OFPUTIL_PACKET_IN_REASON_BUFSIZE];
     struct ofputil_packet_in pin;
     int error;
     int i;
@@ -112,6 +112,14 @@ ofp_print_packet_in(struct ds *string, const struct ofp_header *oh,
         ds_put_format(string, " tun_id=0x%"PRIx64, ntohll(pin.fmd.tun_id));
     }
 
+    if (pin.fmd.tun_src != htonl(0)) {
+        ds_put_format(string, " tun_src="IP_FMT, IP_ARGS(pin.fmd.tun_src));
+    }
+
+    if (pin.fmd.tun_dst != htonl(0)) {
+        ds_put_format(string, " tun_dst="IP_FMT, IP_ARGS(pin.fmd.tun_dst));
+    }
+
     if (pin.fmd.metadata != htonll(0)) {
         ds_put_format(string, " metadata=0x%"PRIx64, ntohll(pin.fmd.metadata));
     }
@@ -123,7 +131,8 @@ ofp_print_packet_in(struct ds *string, const struct ofp_header *oh,
     }
 
     ds_put_format(string, " (via %s)",
-                  ofputil_packet_in_reason_to_string(pin.reason));
+                  ofputil_packet_in_reason_to_string(pin.reason, reasonbuf,
+                                                     sizeof reasonbuf));
 
     ds_put_format(string, " data_len=%zu", pin.packet_len);
     if (pin.buffer_id == UINT32_MAX) {
@@ -144,6 +153,9 @@ ofp_print_packet_in(struct ds *string, const struct ofp_header *oh,
         ds_put_cstr(string, packet);
         free(packet);
     }
+    if (verbosity > 2) {
+        ds_put_hex_dump(string, pin.packet, pin.packet_len, 0, false);
+    }
 }
 
 static void
@@ -176,10 +188,12 @@ ofp_print_packet_out(struct ds *string, const struct ofp_header *oh,
             ds_put_cstr(string, packet);
             free(packet);
         }
+        if (verbosity > 2) {
+            ds_put_hex_dump(string, po.packet, po.packet_len, 0, false);
+        }
     } else {
         ds_put_format(string, " buffer=0x%08"PRIx32, po.buffer_id);
     }
-    ds_put_char(string, '\n');
 
     ofpbuf_uninit(&ofpacts);
 }
@@ -569,6 +583,22 @@ static void print_wild(struct ds *string, const char *leader, int is_wild,
     ds_put_char(string, ',');
 }
 
+static void
+print_wild_port(struct ds *string, const char *leader, int is_wild,
+                int verbosity, uint16_t port)
+{
+    if (is_wild && verbosity < 2) {
+        return;
+    }
+    ds_put_cstr(string, leader);
+    if (!is_wild) {
+        ofputil_format_port(port, string);
+    } else {
+        ds_put_char(string, '*');
+    }
+    ds_put_char(string, ',');
+}
+
 static void
 print_ip_netmask(struct ds *string, const char *leader, ovs_be32 ip,
                  uint32_t wild_bits, int verbosity)
@@ -626,12 +656,16 @@ ofp10_match_to_string(const struct ofp10_match *om, int verbosity)
             ds_put_cstr(&f, "arp,");
         } else if (om->dl_type == htons(ETH_TYPE_RARP)){
             ds_put_cstr(&f, "rarp,");
+        } else if (om->dl_type == htons(ETH_TYPE_MPLS)) {
+            ds_put_cstr(&f, "mpls,");
+        } else if (om->dl_type == htons(ETH_TYPE_MPLS_MCAST)) {
+            ds_put_cstr(&f, "mplsm,");
         } else {
             skip_type = false;
         }
     }
-    print_wild(&f, "in_port=", w & OFPFW10_IN_PORT, verbosity,
-               "%d", ntohs(om->in_port));
+    print_wild_port(&f, "in_port=", w & OFPFW10_IN_PORT, verbosity,
+                    ntohs(om->in_port));
     print_wild(&f, "dl_vlan=", w & OFPFW10_DL_VLAN, verbosity,
                "%d", ntohs(om->dl_vlan));
     print_wild(&f, "dl_vlan_pcp=", w & OFPFW10_DL_VLAN_PCP, verbosity,
@@ -896,20 +930,22 @@ ofp_print_port_mod(struct ds *string, const struct ofp_header *oh)
         return;
     }
 
-    ds_put_format(string, "port: %"PRIu16": addr:"ETH_ADDR_FMT"\n",
-                  pm.port_no, ETH_ADDR_ARGS(pm.hw_addr));
+    ds_put_cstr(string, "port: ");
+    ofputil_format_port(pm.port_no, string);
+    ds_put_format(string, ": addr:"ETH_ADDR_FMT"\n",
+                  ETH_ADDR_ARGS(pm.hw_addr));
 
-    ds_put_format(string, "     config: ");
+    ds_put_cstr(string, "     config: ");
     ofp_print_port_config(string, pm.config);
 
-    ds_put_format(string, "     mask:   ");
+    ds_put_cstr(string, "     mask:   ");
     ofp_print_port_config(string, pm.mask);
 
-    ds_put_format(string, "     advertise: ");
+    ds_put_cstr(string, "     advertise: ");
     if (pm.advertise) {
         ofp_print_port_features(string, pm.advertise);
     } else {
-        ds_put_format(string, "UNCHANGED\n");
+        ds_put_cstr(string, "UNCHANGED\n");
     }
 }
 
@@ -1135,7 +1171,8 @@ ofp_print_ofpst_port_request(struct ds *string, const struct ofp_header *oh)
         return;
     }
 
-    ds_put_format(string, " port_no=%2"PRIu16, ofp10_port);
+    ds_put_cstr(string, " port_no=");
+    ofputil_format_port(ofp10_port, string);
 }
 
 static void
@@ -1162,7 +1199,11 @@ ofp_print_ofpst_port_reply(struct ds *string, const struct ofp_header *oh,
             return;
         }
 
-        ds_put_format(string, "  port %2"PRIu16, ps.port_no);
+        ds_put_cstr(string, "  port ");
+        if (ps.port_no < 10) {
+            ds_put_char(string, ' ');
+        }
+        ofputil_format_port(ps.port_no, string);
 
         ds_put_cstr(string, ": rx ");
         print_port_stat(string, "pkts=", ps.stats.rx_packets, 1);
@@ -1179,6 +1220,12 @@ ofp_print_ofpst_port_reply(struct ds *string, const struct ofp_header *oh,
         print_port_stat(string, "drop=", ps.stats.tx_dropped, 1);
         print_port_stat(string, "errs=", ps.stats.tx_errors, 1);
         print_port_stat(string, "coll=", ps.stats.collisions, 0);
+
+        if (ps.duration_sec != UINT32_MAX) {
+            ds_put_cstr(string, "           duration=");
+            ofp_print_duration(string, ps.duration_sec, ps.duration_nsec);
+            ds_put_char(string, '\n');
+        }
     }
 }
 
@@ -1511,20 +1558,38 @@ ofp_print_echo(struct ds *string, const struct ofp_header *oh, int verbosity)
 }
 
 static void
-ofp_print_nxt_role_message(struct ds *string,
-                           const struct nx_role_request *nrr)
+ofp_print_role_message(struct ds *string, const struct ofp_header *oh)
 {
-    unsigned int role = ntohl(nrr->role);
+    struct ofputil_role_request rr;
+    enum ofperr error;
+
+    error = ofputil_decode_role_message(oh, &rr);
+    if (error) {
+        ofp_print_error(string, error);
+        return;
+    }
 
     ds_put_cstr(string, " role=");
-    if (role == NX_ROLE_OTHER) {
-        ds_put_cstr(string, "other");
-    } else if (role == NX_ROLE_MASTER) {
+
+    switch (rr.role) {
+    case OFPCR12_ROLE_NOCHANGE:
+        ds_put_cstr(string, "nochange");
+        break;
+    case OFPCR12_ROLE_EQUAL:
+        ds_put_cstr(string, "equal"); /* OF 1.2 wording */
+        break;
+    case OFPCR12_ROLE_MASTER:
         ds_put_cstr(string, "master");
-    } else if (role == NX_ROLE_SLAVE) {
+        break;
+    case OFPCR12_ROLE_SLAVE:
         ds_put_cstr(string, "slave");
-    } else {
-        ds_put_format(string, "%u", role);
+        break;
+    default:
+        NOT_REACHED();
+    }
+
+    if (rr.have_generation_id) {
+        ds_put_format(string, " generation_id=%"PRIu64, rr.generation_id);
     }
 }
 
@@ -1598,8 +1663,12 @@ ofp_print_nxt_set_async_config(struct ds *string,
         ds_put_cstr(string, "       PACKET_IN:");
         for (j = 0; j < 32; j++) {
             if (nac->packet_in_mask[i] & htonl(1u << j)) {
-                ds_put_format(string, " %s",
-                              ofputil_packet_in_reason_to_string(j));
+                char reasonbuf[OFPUTIL_PACKET_IN_REASON_BUFSIZE];
+                const char *reason;
+
+                reason = ofputil_packet_in_reason_to_string(j, reasonbuf,
+                                                            sizeof reasonbuf);
+                ds_put_format(string, " %s", reason);
             }
         }
         if (!nac->packet_in_mask[i]) {
@@ -1895,6 +1964,11 @@ ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw,
     case OFPTYPE_BARRIER_REPLY:
         break;
 
+    case OFPTYPE_ROLE_REQUEST:
+    case OFPTYPE_ROLE_REPLY:
+        ofp_print_role_message(string, oh);
+        break;
+
     case OFPTYPE_DESC_STATS_REQUEST:
     case OFPTYPE_PORT_DESC_STATS_REQUEST:
         ofp_print_stats_request(string, oh);
@@ -1955,11 +2029,6 @@ ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw,
         ofp_print_ofpst_port_desc_reply(string, oh);
         break;
 
-    case OFPTYPE_ROLE_REQUEST:
-    case OFPTYPE_ROLE_REPLY:
-        ofp_print_nxt_role_message(string, ofpmsg_body(oh));
-        break;
-
     case OFPTYPE_FLOW_MOD_TABLE_ID:
         ofp_print_nxt_flow_mod_table_id(string, ofpmsg_body(oh));
         break;