ofp-util: Don't return static data in ofputil_packet_in_reason_to_string().
[sliver-openvswitch.git] / lib / ofp-util.c
index 2ca0077..26da477 100644 (file)
@@ -1502,7 +1502,8 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm,
             return error;
         }
 
-        error = ofpacts_pull_openflow11_instructions(&b, b.size, ofpacts);
+        error = ofpacts_pull_openflow11_instructions(&b, b.size, ofm->table_id,
+                                                     ofpacts);
         if (error) {
             return error;
         }
@@ -2014,7 +2015,8 @@ ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *fs,
         }
 
         if (ofpacts_pull_openflow11_instructions(msg, length - sizeof *ofs -
-                                                 padded_match_len, ofpacts)) {
+                                                 padded_match_len,
+                                                 ofs->table_id, ofpacts)) {
             VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_FLOW reply bad instructions");
             return EINVAL;
         }
@@ -2654,11 +2656,13 @@ ofputil_encode_packet_in(const struct ofputil_packet_in *pin,
     return packet;
 }
 
+/* Returns a string form of 'reason'.  The return value is either a statically
+ * allocated constant string or the 'bufsize'-byte buffer 'reasonbuf'.
+ * 'bufsize' should be at least OFPUTIL_PACKET_IN_REASON_BUFSIZE. */
 const char *
-ofputil_packet_in_reason_to_string(enum ofp_packet_in_reason reason)
+ofputil_packet_in_reason_to_string(enum ofp_packet_in_reason reason,
+                                   char *reasonbuf, size_t bufsize)
 {
-    static char s[INT_STRLEN(int) + 1];
-
     switch (reason) {
     case OFPR_NO_MATCH:
         return "no_match";
@@ -2669,8 +2673,8 @@ ofputil_packet_in_reason_to_string(enum ofp_packet_in_reason reason)
 
     case OFPR_N_REASONS:
     default:
-        sprintf(s, "%d", (int) reason);
-        return s;
+        snprintf(reasonbuf, bufsize, "%d", (int) reason);
+        return reasonbuf;
     }
 }
 
@@ -2681,7 +2685,12 @@ ofputil_packet_in_reason_from_string(const char *s,
     int i;
 
     for (i = 0; i < OFPR_N_REASONS; i++) {
-        if (!strcasecmp(s, ofputil_packet_in_reason_to_string(i))) {
+        char reasonbuf[OFPUTIL_PACKET_IN_REASON_BUFSIZE];
+        const char *reason_s;
+
+        reason_s = ofputil_packet_in_reason_to_string(i, reasonbuf,
+                                                      sizeof reasonbuf);
+        if (!strcasecmp(s, reason_s)) {
             *reason = i;
             return true;
         }
@@ -4029,7 +4038,7 @@ ofputil_frag_handling_from_string(const char *s, enum ofp_config_flags *flags)
 /* Converts the OpenFlow 1.1+ port number 'ofp11_port' into an OpenFlow 1.0
  * port number and stores the latter in '*ofp10_port', for the purpose of
  * decoding OpenFlow 1.1+ protocol messages.  Returns 0 if successful,
- * otherwise an OFPERR_* number.
+ * otherwise an OFPERR_* number.  On error, stores OFPP_NONE in '*ofp10_port'.
  *
  * See the definition of OFP11_MAX for an explanation of the mapping. */
 enum ofperr
@@ -4044,6 +4053,7 @@ ofputil_port_from_ofp11(ovs_be32 ofp11_port, uint16_t *ofp10_port)
         *ofp10_port = ofp11_port_h - OFPP11_OFFSET;
         return 0;
     } else {
+        *ofp10_port = OFPP_NONE;
         VLOG_WARN_RL(&bad_ofmsg_rl, "port %"PRIu32" is outside the supported "
                      "range 0 through %d or 0x%"PRIx32" through 0x%"PRIx32,
                      ofp11_port_h, OFPP_MAX - 1,
@@ -4594,11 +4604,8 @@ ofputil_port_stats_to_ofp13(const struct ofputil_port_stats *ops,
                             struct ofp13_port_stats *ps13)
 {
     ofputil_port_stats_to_ofp11(ops, &ps13->ps);
-
-    /* OF 1.3 adds duration fields */
-    /* FIXME: Need to implement port alive duration (sec + nsec) */
-    ps13->duration_sec = htonl(~0);
-    ps13->duration_nsec = htonl(~0);
+    ps13->duration_sec = htonl(ops->duration_sec);
+    ps13->duration_nsec = htonl(ops->duration_nsec);
 }
 
 
@@ -4654,6 +4661,7 @@ ofputil_port_stats_from_ofp10(struct ofputil_port_stats *ops,
     ops->stats.rx_over_errors = ntohll(get_32aligned_be64(&ps10->rx_over_err));
     ops->stats.rx_crc_errors = ntohll(get_32aligned_be64(&ps10->rx_crc_err));
     ops->stats.collisions = ntohll(get_32aligned_be64(&ps10->collisions));
+    ops->duration_sec = ops->duration_nsec = UINT32_MAX;
 
     return 0;
 }
@@ -4682,6 +4690,7 @@ ofputil_port_stats_from_ofp11(struct ofputil_port_stats *ops,
     ops->stats.rx_over_errors = ntohll(ps11->rx_over_err);
     ops->stats.rx_crc_errors = ntohll(ps11->rx_crc_err);
     ops->stats.collisions = ntohll(ps11->collisions);
+    ops->duration_sec = ops->duration_nsec = UINT32_MAX;
 
     return 0;
 }
@@ -4690,13 +4699,11 @@ static enum ofperr
 ofputil_port_stats_from_ofp13(struct ofputil_port_stats *ops,
                               const struct ofp13_port_stats *ps13)
 {
-    enum ofperr error =
-        ofputil_port_stats_from_ofp11(ops, &ps13->ps);
+    enum ofperr error = ofputil_port_stats_from_ofp11(ops, &ps13->ps);
     if (!error) {
-        /* FIXME: Get ps13->duration_sec and ps13->duration_nsec,
-         * Add to netdev_stats? */
+        ops->duration_sec = ntohl(ps13->duration_sec);
+        ops->duration_nsec = ntohl(ps13->duration_nsec);
     }
-
     return error;
 }