From fa2bad0ffc080ba8751421bdc2465f883d26e8bc Mon Sep 17 00:00:00 2001
From: Ben Pfaff <blp@nicira.com>
Date: Thu, 9 Aug 2012 11:01:48 -0700
Subject: [PATCH] Add support for 'hard_timeout' in OF1.2 flow_removed message.

ofputil_decode_flow_removed() doesn't yet support OF1.2 at all so that
piece is missing but this otherwise should be complete.

CC: Simon Horman <horms@verge.net.au>
Signed-off-by: Ben Pfaff <blp@nicira.com>
---
 lib/ofp-print.c   | 10 ++++++++--
 lib/ofp-util.c    |  3 +++
 lib/ofp-util.h    |  1 +
 ofproto/ofproto.c |  1 +
 4 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/lib/ofp-print.c b/lib/ofp-print.c
index b4b8bb6a8..5a8b86748 100644
--- a/lib/ofp-print.c
+++ b/lib/ofp-print.c
@@ -856,8 +856,14 @@ ofp_print_flow_removed(struct ds *string, const struct ofp_header *oh)
     }
     ds_put_cstr(string, " duration");
     ofp_print_duration(string, fr.duration_sec, fr.duration_nsec);
-    ds_put_format(string, " idle%"PRIu16" pkts%"PRIu64" bytes%"PRIu64"\n",
-         fr.idle_timeout, fr.packet_count, fr.byte_count);
+    ds_put_format(string, " idle%"PRIu16, fr.idle_timeout);
+    if (fr.hard_timeout) {
+        /* The hard timeout was only added in OF1.2, so only print it if it is
+         * actually in use to avoid gratuitous change to the formatting. */
+        ds_put_format(string, " hard%"PRIu16, fr.hard_timeout);
+    }
+    ds_put_format(string, " pkts%"PRIu64" bytes%"PRIu64"\n",
+                  fr.packet_count, fr.byte_count);
 }
 
 static void
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 2e52d5390..a8030ff58 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -1837,6 +1837,7 @@ ofputil_decode_flow_removed(struct ofputil_flow_removed *fr,
         fr->duration_sec = ntohl(ofr->duration_sec);
         fr->duration_nsec = ntohl(ofr->duration_nsec);
         fr->idle_timeout = ntohs(ofr->idle_timeout);
+        fr->hard_timeout = 0;
         fr->packet_count = ntohll(ofr->packet_count);
         fr->byte_count = ntohll(ofr->byte_count);
     } else if (raw == OFPRAW_NXT_FLOW_REMOVED) {
@@ -1858,6 +1859,7 @@ ofputil_decode_flow_removed(struct ofputil_flow_removed *fr,
         fr->duration_sec = ntohl(nfr->duration_sec);
         fr->duration_nsec = ntohl(nfr->duration_nsec);
         fr->idle_timeout = ntohs(nfr->idle_timeout);
+        fr->hard_timeout = 0;
         fr->packet_count = ntohll(nfr->packet_count);
         fr->byte_count = ntohll(nfr->byte_count);
     } else {
@@ -1891,6 +1893,7 @@ ofputil_encode_flow_removed(const struct ofputil_flow_removed *fr,
         ofr->duration_sec = htonl(fr->duration_sec);
         ofr->duration_nsec = htonl(fr->duration_nsec);
         ofr->idle_timeout = htons(fr->idle_timeout);
+        ofr->hard_timeout = htons(fr->hard_timeout);
         ofr->packet_count = htonll(fr->packet_count);
         ofr->byte_count = htonll(fr->byte_count);
         oxm_put_match(msg, &fr->rule);
diff --git a/lib/ofp-util.h b/lib/ofp-util.h
index 51f0f5a7b..9cc30289a 100644
--- a/lib/ofp-util.h
+++ b/lib/ofp-util.h
@@ -248,6 +248,7 @@ struct ofputil_flow_removed {
     uint32_t duration_sec;
     uint32_t duration_nsec;
     uint16_t idle_timeout;
+    uint16_t hard_timeout;
     uint64_t packet_count;      /* Packet count, UINT64_MAX if unknown. */
     uint64_t byte_count;        /* Byte count, UINT64_MAX if unknown. */
 };
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index cf31a3b24..8c10f19a1 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -3142,6 +3142,7 @@ ofproto_rule_send_removed(struct rule *rule, uint8_t reason)
     calc_flow_duration__(rule->created, time_msec(),
                          &fr.duration_sec, &fr.duration_nsec);
     fr.idle_timeout = rule->idle_timeout;
+    fr.hard_timeout = rule->hard_timeout;
     rule->ofproto->ofproto_class->rule_get_stats(rule, &fr.packet_count,
                                                  &fr.byte_count);
 
-- 
2.47.0