ofputil: New function ofputil_decode_packet_in().
authorEthan Jackson <ethan@nicira.com>
Fri, 23 Dec 2011 00:35:23 +0000 (16:35 -0800)
committerEthan Jackson <ethan@nicira.com>
Tue, 10 Jan 2012 22:30:15 +0000 (14:30 -0800)
Signed-off-by: Ethan Jackson <ethan@nicira.com>
lib/ofp-print.c
lib/ofp-util.c
lib/ofp-util.h
ofproto/ofproto-dpif.c

index 20b653776e614f7b2b873662858cfa30f9616eab..c4f0b8a665e94aaa77496c6d42784dae4dbd21dc 100644 (file)
@@ -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);
     }
index c3ee54e250c26be96ae3b48a8b2980a30f545457..17b3cc75e862b285d619f1c2b81eb4c48d8555a2 100644 (file)
@@ -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 *
index b9c2d54e4e002a2e8b23366820f0139df46046f0..1837f327e74d897bfdc29289d68e9a711f95fa1c 100644 (file)
@@ -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. */
index ac74bd16884ff9b0c1bca09996b59587337239ad..03bf36840f713a7a9761b19cfb6cabccdba19732 100644 (file)
@@ -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 */