ofproto: Use ofconn_send_reply() for sending OpenFlow replies.
[openvswitch] / lib / ofp-util.c
index 3d64fcf1e4e8bf09dd72b0a90a012b7bb26ccf72..d91fbb11fe1e287a2bd6c9bd5128e6f467b2ceab 100644 (file)
@@ -1453,6 +1453,49 @@ ofputil_encode_flow_removed(const struct ofputil_flow_removed *fr,
     return msg;
 }
 
+/* Converts abstract ofputil_packet_in 'pin' into an OFPT_PACKET_IN message
+ * and returns the message.
+ *
+ * If 'rw_packet' is NULL, the caller takes ownership of the newly allocated
+ * returned ofpbuf.
+ *
+ * If 'rw_packet' is nonnull, then it must contain the same data as
+ * pin->packet.  'rw_packet' is allowed to be the same ofpbuf as pin->packet.
+ * It is modified in-place into an OFPT_PACKET_IN message according to 'pin',
+ * and then ofputil_encode_packet_in() returns 'rw_packet'.  If 'rw_packet' has
+ * enough headroom to insert a "struct ofp_packet_in", this is more efficient
+ * than ofputil_encode_packet_in() because it does not copy the packet
+ * payload. */
+struct ofpbuf *
+ofputil_encode_packet_in(const struct ofputil_packet_in *pin,
+                        struct ofpbuf *rw_packet)
+{
+    int total_len = pin->packet->size;
+    struct ofp_packet_in *opi;
+
+    if (rw_packet) {
+        if (pin->send_len < rw_packet->size) {
+            rw_packet->size = pin->send_len;
+        }
+    } else {
+        rw_packet = ofpbuf_clone_data_with_headroom(
+            pin->packet->data, MIN(pin->send_len, pin->packet->size),
+            offsetof(struct ofp_packet_in, data));
+    }
+
+    /* Add OFPT_PACKET_IN. */
+    opi = ofpbuf_push_zeros(rw_packet, offsetof(struct ofp_packet_in, data));
+    opi->header.version = OFP_VERSION;
+    opi->header.type = OFPT_PACKET_IN;
+    opi->total_len = htons(total_len);
+    opi->in_port = htons(pin->in_port);
+    opi->reason = pin->reason;
+    opi->buffer_id = htonl(pin->buffer_id);
+    update_openflow_length(rw_packet);
+
+    return rw_packet;
+}
+
 /* 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",
@@ -1820,6 +1863,19 @@ make_echo_reply(const struct ofp_header *rq)
     return out;
 }
 
+/* Converts the members of 'opp' from host to network byte order. */
+void
+hton_ofp_phy_port(struct ofp_phy_port *opp)
+{
+    opp->port_no = htons(opp->port_no);
+    opp->config = htonl(opp->config);
+    opp->state = htonl(opp->state);
+    opp->curr = htonl(opp->curr);
+    opp->advertised = htonl(opp->advertised);
+    opp->supported = htonl(opp->supported);
+    opp->peer = htonl(opp->peer);
+}
+
 const struct ofp_flow_stats *
 flow_stats_first(struct flow_stats_iterator *iter,
                  const struct ofp_stats_reply *osr)