[ovs-dev] [packet_in v2 13/18] ofputil: New function ofputil_decode_packet_in().

Ethan Jackson ethan at nicira.com
Sat Jan 7 19:11:54 UTC 2012


Signed-off-by: Ethan Jackson <ethan at nicira.com>
---
 lib/ofp-print.c        |   39 +++++++++++++++++++++++----------------
 lib/ofp-util.c         |   29 +++++++++++++++++++++++++++++
 lib/ofp-util.h         |    3 +++
 ofproto/ofproto-dpif.c |    2 ++
 4 files changed, 57 insertions(+), 16 deletions(-)

diff --git a/lib/ofp-print.c b/lib/ofp-print.c
index 20b6537..c4f0b8a 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_len);
+    if (pin.buffer_id == UINT32_MAX) {
         ds_put_format(string, " (unbuffered)");
-        if (ntohs(op->total_len) != data_len)
+        if (pin.total_len != pin.packet_len) {
             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_len) {
             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, pin.packet_len);
         ds_put_cstr(string, packet);
         free(packet);
     }
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index c3ee54e..17b3cc7 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -1542,6 +1542,35 @@ 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);
+    memset(pin, 0, sizeof *pin);
+
+    if (code == OFPUTIL_OFPT_PACKET_IN) {
+        const struct ofp_packet_in *opi = (const struct ofp_packet_in *) oh;
+
+        pin->packet = opi->data;
+        pin->packet_len = 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);
+    } else {
+        NOT_REACHED();
+    }
+
+    return 0;
+}
+
 /* Converts abstract ofputil_packet_in 'pin' into an OFPT_PACKET_IN message
  * and returns the message. */
 struct ofpbuf *
diff --git a/lib/ofp-util.h b/lib/ofp-util.h
index b9c2d54..1837f32 100644
--- a/lib/ofp-util.h
+++ b/lib/ofp-util.h
@@ -222,8 +222,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 *);
 
 /* OpenFlow protocol utility functions. */
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index ac74bd1..03bf368 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -2419,6 +2419,7 @@ send_packet_in_miss(struct ofproto_dpif *ofproto, struct ofpbuf *packet,
 
     pin.packet = packet->data;
     pin.packet_len = packet->size;
+    pin.total_len = packet->size;
     pin.in_port = flow->in_port;
     pin.reason = OFPR_NO_MATCH;
     pin.buffer_id = 0;          /* not yet known */
@@ -2443,6 +2444,7 @@ send_packet_in_action(struct ofproto_dpif *ofproto, struct ofpbuf *packet,
 
     pin.packet = packet->data;
     pin.packet_len = packet->size;
+    pin.total_len = packet->size;
     pin.in_port = flow->in_port;
     pin.reason = OFPR_ACTION;
     pin.buffer_id = 0;          /* not yet known */
-- 
1.7.7.1




More information about the dev mailing list