---
 lib/ofp-print.c        |   39 +++++++++++++++++++++++----------------
 lib/ofp-util.c         |   28 ++++++++++++++++++++++++++++
 lib/ofp-util.h         |    3 +++
 ofproto/ofproto-dpif.c |    2 ++
 4 files changed, 56 insertions(+), 16 deletions(-)

diff --git a/lib/ofp-print.c b/lib/ofp-print.c
index 37c5823..afbbca1 100644
--- a/lib/ofp-print.c
+++ b/lib/ofp-print.c
@@ -79,36 +79,43 @@ ofp_packet_to_string(const void *data, size_t len)
 }
 
 static void
-ofp_print_packet_in(struct ds *string, const struct ofp_packet_in *op,
+ofp_print_packet_in(struct ds *string, const struct ofp_header *oh,
                     int verbosity)
 {
-    size_t len = ntohs(op->header.length);
-    size_t data_len;
+    struct ofputil_packet_in pin;
+    int error;
 
-    ds_put_format(string, " total_len=%"PRIu16" in_port=",
-                  ntohs(op->total_len));
-    ofputil_format_port(ntohs(op->in_port), string);
+    error = ofputil_decode_packet_in(&pin, oh);
+    if (error) {
+        ofp_print_error(string, error);
+        return;
+    }
 
-    if (op->reason == OFPR_ACTION)
+    ds_put_format(string, " total_len=%"PRIu16" in_port=", pin.total_len);
+    ofputil_format_port(pin.in_port, string);
+
+    if (pin.reason == OFPR_ACTION) {
         ds_put_cstr(string, " (via action)");
-    else if (op->reason != OFPR_NO_MATCH)
-        ds_put_format(string, " (***reason %"PRIu8"***)", op->reason);
+    } else if (pin.reason != OFPR_NO_MATCH) {
+        ds_put_format(string, " (***reason %"PRIu8"***)", pin.reason);
+    }
 
-    data_len = len - offsetof(struct ofp_packet_in, data);
-    ds_put_format(string, " data_len=%zu", data_len);
-    if (op->buffer_id == htonl(UINT32_MAX)) {
+    ds_put_format(string, " data_len=%zu", pin.packet.size);
+    if (pin.buffer_id == UINT32_MAX) {
         ds_put_format(string, " (unbuffered)");
-        if (ntohs(op->total_len) != data_len)
+        if (pin.total_len != pin.packet.size) {
             ds_put_format(string, " (***total_len != data_len***)");
+        }
     } else {
-        ds_put_format(string, " buffer=0x%08"PRIx32, ntohl(op->buffer_id));
-        if (ntohs(op->total_len) < data_len)
+        ds_put_format(string, " buffer=0x%08"PRIx32, pin.buffer_id);
+        if (pin.total_len < pin.packet.size) {
             ds_put_format(string, " (***total_len < data_len***)");
+        }
     }
     ds_put_char(string, '\n');
 
     if (verbosity > 0) {
-        char *packet = ofp_packet_to_string(op->data, data_len);
+        char *packet = ofp_packet_to_string(pin.packet.data, pin.packet.size);
         ds_put_cstr(string, packet);
         free(packet);
     }
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 3a14013..0999a9a 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -1522,6 +1522,34 @@ ofputil_encode_flow_removed(const struct 
ofputil_flow_removed *fr,
     return msg;
 }
 
+int
+ofputil_decode_packet_in(struct ofputil_packet_in *pin,
+                         const struct ofp_header *oh)
+{
+    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_PACKET_IN) {
+        const struct ofp_packet_in *opi = (const struct ofp_packet_in *) oh;
+
+        ofpbuf_use_const(&pin->packet, opi->data,
+                         (ntohs(opi->header.length)
+                          - offsetof(struct ofp_packet_in, data)));
+        pin->in_port = ntohs(opi->in_port);
+        pin->reason = opi->reason;
+        pin->buffer_id = ntohl(opi->buffer_id);
+        pin->total_len = ntohs(opi->total_len);
+        pin->send_len = 0;
+    } else {
+        NOT_REACHED();
+    }
+
+    return 0;
+}
+
 /* Converts abstract ofputil_packet_in 'pin' into an OFPT_PACKET_IN message
  * and returns the message.
  *
diff --git a/lib/ofp-util.h b/lib/ofp-util.h
index 5a11a69..b8efb74 100644
--- a/lib/ofp-util.h
+++ b/lib/ofp-util.h
@@ -217,8 +217,11 @@ struct ofputil_packet_in {
 
     uint32_t buffer_id;
     int send_len;
+    uint16_t total_len;         /* Full length of frame. */
 };
 
+int ofputil_decode_packet_in(struct ofputil_packet_in *,
+                             const struct ofp_header *);
 struct ofpbuf *ofputil_encode_packet_in(const struct ofputil_packet_in *,
                                         struct ofpbuf *rw_packet);
 
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 2038302..33d5c2e 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -2410,6 +2410,7 @@ send_packet_in_miss(struct ofproto_dpif *ofproto, struct 
ofpbuf *packet,
     pin.reason = OFPR_NO_MATCH;
     pin.buffer_id = 0;          /* not yet known */
     pin.send_len = 0;           /* not used for flow table misses */
+    pin.total_len = packet->size;
     ofpbuf_use_const(&pin.packet, packet->data, packet->size);
     connmgr_send_packet_in(ofproto->up.connmgr, &pin, flow,
                            clone ? NULL : packet);
@@ -2437,6 +2438,7 @@ send_packet_in_action(struct ofproto_dpif *ofproto, 
struct ofpbuf *packet,
     pin.reason = OFPR_ACTION;
     pin.buffer_id = 0;          /* not yet known */
     pin.send_len = cookie.data;
+    pin.total_len = packet->size;
     ofpbuf_use_const(&pin.packet, packet->data, packet->size);
     connmgr_send_packet_in(ofproto->up.connmgr, &pin, flow,
                            clone ? NULL : packet);
-- 
1.7.7.1

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to