ofp-print: Print OFPUTIL_NXT_FLOW_REMOVED.
authorBen Pfaff <blp@nicira.com>
Thu, 9 Dec 2010 18:31:49 +0000 (10:31 -0800)
committerBen Pfaff <blp@nicira.com>
Thu, 9 Dec 2010 18:31:49 +0000 (10:31 -0800)
lib/ofp-print.c
lib/ofp-util.c
lib/ofp-util.h

index 56111435328e228d72b5762327a80c91fbb5489a..840356c5b30f8444217dfd5e61d2f0dd77c78582 100644 (file)
@@ -866,12 +866,21 @@ ofp_print_duration(struct ds *string, unsigned int sec, unsigned int nsec)
 }
 
 static void
-ofp_print_flow_removed(struct ds *string, const struct ofp_flow_removed *ofr,
-                       int verbosity)
+ofp_print_flow_removed(struct ds *string, const struct ofp_header *oh)
 {
-    ofp_print_match(string, &ofr->match, verbosity);
+    struct ofputil_flow_removed fr;
+    int error;
+
+    error = ofputil_decode_flow_removed(&fr, oh, NXFF_OPENFLOW10);
+    if (error) {
+        ofp_print_error(string, error);
+        return;
+    }
+
+    cls_rule_format(&fr.rule, string);
+
     ds_put_cstr(string, " reason=");
-    switch (ofr->reason) {
+    switch (fr.reason) {
     case OFPRR_IDLE_TIMEOUT:
         ds_put_cstr(string, "idle");
         break;
@@ -882,22 +891,17 @@ ofp_print_flow_removed(struct ds *string, const struct ofp_flow_removed *ofr,
         ds_put_cstr(string, "delete");
         break;
     default:
-        ds_put_format(string, "**%"PRIu8"**", ofr->reason);
+        ds_put_format(string, "**%"PRIu8"**", fr.reason);
         break;
     }
 
-    if (ofr->cookie != htonll(0)) {
-        ds_put_format(string, " cookie:0x%"PRIx64, ntohll(ofr->cookie));
-    }
-    if (ofr->priority != htons(32768)) {
-        ds_put_format(string, " pri:%"PRIu16, ntohs(ofr->priority));
+    if (fr.cookie != htonll(0)) {
+        ds_put_format(string, " cookie:0x%"PRIx64, ntohll(fr.cookie));
     }
     ds_put_cstr(string, " duration");
-    ofp_print_duration(string,
-                       ntohl(ofr->duration_sec), ntohl(ofr->duration_nsec));
+    ofp_print_duration(string, fr.duration_sec, fr.duration_nsec);
     ds_put_format(string, " idle%"PRIu16" pkts%"PRIu64" bytes%"PRIu64"\n",
-         ntohs(ofr->idle_timeout), ntohll(ofr->packet_count),
-         ntohll(ofr->byte_count));
+         fr.idle_timeout, fr.packet_count, fr.byte_count);
 }
 
 static void
@@ -1561,7 +1565,8 @@ ofp_to_string__(const struct ofp_header *oh,
         break;
 
     case OFPUTIL_OFPT_FLOW_REMOVED:
-        ofp_print_flow_removed(string, msg, verbosity);
+    case OFPUTIL_NXT_FLOW_REMOVED:
+        ofp_print_flow_removed(string, msg);
         break;
 
     case OFPUTIL_OFPT_PORT_STATUS:
@@ -1667,17 +1672,13 @@ ofp_to_string__(const struct ofp_header *oh,
         ofp_print_flow_mod(string, msg, code, verbosity);
         break;
 
-    case OFPUTIL_NXT_FLOW_REMOVED:
-        /* XXX */
-        break;
-
     case OFPUTIL_NXST_FLOW_REPLY:
         ofp_print_nxst_flow_reply(string, oh);
         break;
 
     case OFPUTIL_NXST_AGGREGATE_REPLY:
         ofp_print_stats_reply(string, oh);
-        ofp_print_nxst_aggregate_reply(string, oh);
+        ofp_print_nxst_aggregate_reply(string, msg);
         break;
     }
 }
index c296f20199cb296a5da682c99bcead1d542b9881..50dd137194198ba4428706d0560c7c5a8f37e01a 100644 (file)
@@ -1067,7 +1067,11 @@ ofputil_decode_nxst_flow_request(struct flow_stats_request *fsr,
 /* Converts an OFPST_FLOW, OFPST_AGGREGATE, NXST_FLOW, or NXST_AGGREGATE
  * message 'oh', received when the current flow format was 'flow_format', into
  * an abstract flow_stats_request in 'fsr'.  Returns 0 if successful, otherwise
- * an OpenFlow error code. */
+ * an OpenFlow error code.
+ *
+ * For OFPST_FLOW and OFPST_AGGREGATE messages, 'flow_format' should be the
+ * current flow format at the time when the message was received.  Otherwise
+ * 'flow_format' is ignored. */
 int
 ofputil_decode_flow_stats_request(struct flow_stats_request *fsr,
                                   const struct ofp_header *oh,
@@ -1140,6 +1144,68 @@ ofputil_encode_flow_stats_request(const struct flow_stats_request *fsr,
     return msg;
 }
 
+/* Converts an OFPT_FLOW_REMOVED or NXT_FLOW_REMOVED message 'oh', received
+ * when the current flow format was 'flow_format', into an abstract
+ * ofputil_flow_removed in 'fr'.  Returns 0 if successful, otherwise an
+ * OpenFlow error code.
+ *
+ * For OFPT_FLOW_REMOVED messages, 'flow_format' should be the current flow
+ * format at the time when the message was received.  Otherwise 'flow_format'
+ * is ignored. */
+int
+ofputil_decode_flow_removed(struct ofputil_flow_removed *fr,
+                            const struct ofp_header *oh,
+                            enum nx_flow_format flow_format)
+{
+    const struct ofputil_msg_type *type;
+    enum ofputil_msg_code code;
+
+    ofputil_decode_msg_type(oh, &type);
+    code = ofputil_msg_type_code(type);
+    if (code == OFPUTIL_OFPT_FLOW_REMOVED) {
+        const struct ofp_flow_removed *ofr;
+
+        ofr = (const struct ofp_flow_removed *) oh;
+        ofputil_cls_rule_from_match(&ofr->match, ntohs(ofr->priority),
+                                    flow_format, ofr->cookie, &fr->rule);
+        fr->cookie = ofr->cookie;
+        fr->reason = ofr->reason;
+        fr->duration_sec = ntohl(ofr->duration_sec);
+        fr->duration_nsec = ntohl(ofr->duration_nsec);
+        fr->idle_timeout = ntohs(ofr->idle_timeout);
+        fr->packet_count = ntohll(ofr->packet_count);
+        fr->byte_count = ntohll(ofr->byte_count);
+    } else if (code == OFPUTIL_NXT_FLOW_REMOVED) {
+        struct nx_flow_removed *nfr;
+        struct ofpbuf b;
+        int error;
+
+        ofpbuf_use_const(&b, oh, ntohs(oh->length));
+
+        nfr = ofpbuf_pull(&b, sizeof *nfr);
+        error = nx_pull_match(&b, ntohs(nfr->match_len), ntohs(nfr->priority),
+                              &fr->rule);
+        if (error) {
+            return error;
+        }
+        if (b.size) {
+            return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
+        }
+
+        fr->cookie = nfr->cookie;
+        fr->reason = nfr->reason;
+        fr->duration_sec = ntohl(nfr->duration_sec);
+        fr->duration_nsec = ntohl(nfr->duration_nsec);
+        fr->idle_timeout = ntohs(nfr->idle_timeout);
+        fr->packet_count = ntohll(nfr->packet_count);
+        fr->byte_count = ntohll(nfr->byte_count);
+    } else {
+        NOT_REACHED();
+    }
+
+    return 0;
+}
+
 /* Returns a string representing the message type of 'type'.  The string is the
  * enumeration constant for the type, e.g. "OFPT_HELLO".  For statistics
  * messages, the constant is followed by "request" or "reply",
index c3ed2b80201fb834cd93e61f969f059a90a268c2..ea7939c195117a353ca095addced47bb626ca6c2 100644 (file)
@@ -155,6 +155,22 @@ int ofputil_decode_flow_stats_request(struct flow_stats_request *,
 struct ofpbuf *ofputil_encode_flow_stats_request(
     const struct flow_stats_request *, enum nx_flow_format);
 
+/* Flow removed message, independent of flow format. */
+struct ofputil_flow_removed {
+    struct cls_rule rule;
+    ovs_be64 cookie;
+    uint8_t reason;             /* One of OFPRR_*. */
+    uint32_t duration_sec;
+    uint32_t duration_nsec;
+    uint16_t idle_timeout;
+    uint64_t packet_count;
+    uint64_t byte_count;
+};
+
+int ofputil_decode_flow_removed(struct ofputil_flow_removed *,
+                                const struct ofp_header *,
+                                enum nx_flow_format);
+
 /* OpenFlow protocol utility functions. */
 void *make_openflow(size_t openflow_len, uint8_t type, struct ofpbuf **);
 void *make_nxmsg(size_t openflow_len, uint32_t subtype, struct ofpbuf **);