ofproto: Factor building of flow_removed messages out into ofp-util.
authorBen Pfaff <blp@nicira.com>
Tue, 15 Mar 2011 16:49:14 +0000 (09:49 -0700)
committerBen Pfaff <blp@nicira.com>
Tue, 29 Mar 2011 19:28:10 +0000 (12:28 -0700)
This removes some code from ofproto.c.

lib/ofp-util.c
lib/ofp-util.h
ofproto/ofproto.c

index 9c894d7..3d64fcf 100644 (file)
@@ -1405,6 +1405,54 @@ ofputil_decode_flow_removed(struct ofputil_flow_removed *fr,
     return 0;
 }
 
+/* Converts abstract ofputil_flow_removed 'fr' into an OFPT_FLOW_REMOVED or
+ * NXT_FLOW_REMOVED message 'oh' according to 'flow_format', and returns the
+ * message. */
+struct ofpbuf *
+ofputil_encode_flow_removed(const struct ofputil_flow_removed *fr,
+                            enum nx_flow_format flow_format)
+{
+    struct ofpbuf *msg;
+
+    if (flow_format == NXFF_OPENFLOW10
+        || flow_format == NXFF_TUN_ID_FROM_COOKIE) {
+        struct ofp_flow_removed *ofr;
+
+        ofr = make_openflow_xid(sizeof *ofr, OFPT_FLOW_REMOVED, htonl(0),
+                                &msg);
+        ofputil_cls_rule_to_match(&fr->rule, flow_format, &ofr->match,
+                                  fr->cookie, &ofr->cookie);
+        ofr->priority = htons(fr->rule.priority);
+        ofr->reason = fr->reason;
+        ofr->duration_sec = htonl(fr->duration_sec);
+        ofr->duration_nsec = htonl(fr->duration_nsec);
+        ofr->idle_timeout = htons(fr->idle_timeout);
+        ofr->packet_count = htonll(fr->packet_count);
+        ofr->byte_count = htonll(fr->byte_count);
+    } else if (flow_format == NXFF_NXM) {
+        struct nx_flow_removed *nfr;
+        int match_len;
+
+        make_nxmsg_xid(sizeof *nfr, NXT_FLOW_REMOVED, htonl(0), &msg);
+        match_len = nx_put_match(msg, &fr->rule);
+
+        nfr = msg->data;
+        nfr->cookie = fr->cookie;
+        nfr->priority = htons(fr->rule.priority);
+        nfr->reason = fr->reason;
+        nfr->duration_sec = htonl(fr->duration_sec);
+        nfr->duration_nsec = htonl(fr->duration_nsec);
+        nfr->idle_timeout = htons(fr->idle_timeout);
+        nfr->match_len = htons(match_len);
+        nfr->packet_count = htonll(fr->packet_count);
+        nfr->byte_count = htonll(fr->byte_count);
+    } else {
+        NOT_REACHED();
+    }
+
+    return msg;
+}
+
 /* 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 439495b..c31165b 100644 (file)
@@ -189,6 +189,8 @@ struct ofputil_flow_removed {
 int ofputil_decode_flow_removed(struct ofputil_flow_removed *,
                                 const struct ofp_header *,
                                 enum nx_flow_format);
+struct ofpbuf *ofputil_encode_flow_removed(const struct ofputil_flow_removed *,
+                                           enum nx_flow_format);
 
 /* OpenFlow protocol utility functions. */
 void *make_openflow(size_t openflow_len, uint8_t type, struct ofpbuf **);
index e0715b9..6fd8833 100644 (file)
@@ -3546,11 +3546,21 @@ handle_port_stats_request(struct ofconn *ofconn, const struct ofp_header *oh)
 }
 
 static void
-calc_flow_duration(long long int start, ovs_be32 *sec, ovs_be32 *nsec)
+calc_flow_duration__(long long int start, uint32_t *sec, uint32_t *nsec)
 {
     long long int msecs = time_msec() - start;
-    *sec = htonl(msecs / 1000);
-    *nsec = htonl((msecs % 1000) * (1000 * 1000));
+    *sec = msecs / 1000;
+    *nsec = (msecs % 1000) * (1000 * 1000);
+}
+
+static void
+calc_flow_duration(long long int start, ovs_be32 *sec_be, ovs_be32 *nsec_be)
+{
+    uint32_t sec, nsec;
+
+    calc_flow_duration__(start, &sec, &nsec);
+    *sec_be = htonl(sec);
+    *nsec_be = htonl(nsec);
 }
 
 static void
@@ -4866,76 +4876,37 @@ rule_expire(struct ofproto *ofproto, struct rule *rule)
     rule_remove(ofproto, rule);
 }
 \f
-static struct ofpbuf *
-compose_ofp_flow_removed(struct ofconn *ofconn, const struct rule *rule,
-                         uint8_t reason)
-{
-    struct ofp_flow_removed *ofr;
-    struct ofpbuf *buf;
-
-    ofr = make_openflow_xid(sizeof *ofr, OFPT_FLOW_REMOVED, htonl(0), &buf);
-    ofputil_cls_rule_to_match(&rule->cr, ofconn->flow_format, &ofr->match,
-                              rule->flow_cookie, &ofr->cookie);
-    ofr->priority = htons(rule->cr.priority);
-    ofr->reason = reason;
-    calc_flow_duration(rule->created, &ofr->duration_sec, &ofr->duration_nsec);
-    ofr->idle_timeout = htons(rule->idle_timeout);
-    ofr->packet_count = htonll(rule->packet_count);
-    ofr->byte_count = htonll(rule->byte_count);
-
-    return buf;
-}
-
-static struct ofpbuf *
-compose_nx_flow_removed(const struct rule *rule, uint8_t reason)
-{
-    struct nx_flow_removed *nfr;
-    struct ofpbuf *buf;
-    int match_len;
-
-    make_nxmsg_xid(sizeof *nfr, NXT_FLOW_REMOVED, htonl(0), &buf);
-    match_len = nx_put_match(buf, &rule->cr);
-
-    nfr = buf->data;
-    nfr->cookie = rule->flow_cookie;
-    nfr->priority = htons(rule->cr.priority);
-    nfr->reason = reason;
-    calc_flow_duration(rule->created, &nfr->duration_sec, &nfr->duration_nsec);
-    nfr->idle_timeout = htons(rule->idle_timeout);
-    nfr->match_len = htons(match_len);
-    nfr->packet_count = htonll(rule->packet_count);
-    nfr->byte_count = htonll(rule->byte_count);
-
-    return buf;
-}
-
 static void
 rule_send_removed(struct ofproto *p, struct rule *rule, uint8_t reason)
 {
+    struct ofputil_flow_removed fr;
     struct ofconn *ofconn;
 
     if (!rule->send_flow_removed) {
         return;
     }
 
-    LIST_FOR_EACH (ofconn, node, &p->all_conns) {
-        struct ofpbuf *msg;
+    fr.rule = rule->cr;
+    fr.cookie = rule->flow_cookie;
+    fr.reason = reason;
+    calc_flow_duration__(rule->created, &fr.duration_sec, &fr.duration_nsec);
+    fr.idle_timeout = rule->idle_timeout;
+    fr.packet_count = rule->packet_count;
+    fr.byte_count = rule->byte_count;
 
+    LIST_FOR_EACH (ofconn, node, &p->all_conns) {
         if (!rconn_is_connected(ofconn->rconn)
             || !ofconn_receives_async_msgs(ofconn)) {
             continue;
         }
 
-        msg = (ofconn->flow_format == NXFF_NXM
-               ? compose_nx_flow_removed(rule, reason)
-               : compose_ofp_flow_removed(ofconn, rule, reason));
-
         /* Account flow expirations under ofconn->reply_counter, the counter
          * for replies to OpenFlow requests.  That works because preventing
          * OpenFlow requests from being processed also prevents new flows from
          * being added (and expiring).  (It also prevents processing OpenFlow
          * requests that would not add new flows, so it is imperfect.) */
-        queue_tx(msg, ofconn, ofconn->reply_counter);
+        queue_tx(ofputil_encode_flow_removed(&fr, ofconn->flow_format),
+                 ofconn, ofconn->reply_counter);
     }
 }