---
 lib/ofp-util.c |   70 ++++++++++++++++++++++++++++++++-----------------------
 lib/ofp-util.h |    2 +
 2 files changed, 43 insertions(+), 29 deletions(-)

diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 1e95d04..156d974 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -343,14 +343,13 @@ ofputil_check_length(const struct ofputil_msg_type *type, 
unsigned int size)
 }
 
 static int
-ofputil_decode_vendor(const struct ofp_header *oh,
+ofputil_decode_vendor(const struct ofp_header *oh, size_t length,
                       const struct ofputil_msg_type **typep)
 {
     const char *category = "Nicira extension message";
     const struct ofp_vendor_header *ovh;
     const struct ofputil_msg_type *type;
     const struct nicira_header *nh;
-    size_t length = ntohs(oh->length);
 
     if (length < sizeof(struct ofp_vendor_header)) {
         VLOG_WARN_RL(&bad_ofmsg_rl, "truncated vendor message");
@@ -392,10 +391,9 @@ ofputil_decode_vendor(const struct ofp_header *oh,
 }
 
 static int
-check_nxstats_msg(const struct ofp_header *oh)
+check_nxstats_msg(const struct ofp_header *oh, size_t length)
 {
     const struct ofp_vendor_stats_msg *ovsm;
-    size_t length = ntohs(oh->length);
 
     if (length < sizeof(struct ofp_vendor_stats_msg)) {
         VLOG_WARN_RL(&bad_ofmsg_rl, "truncated vendor stats message");
@@ -418,7 +416,7 @@ check_nxstats_msg(const struct ofp_header *oh)
 }
 
 static int
-ofputil_decode_nxst_request(const struct ofp_header *oh,
+ofputil_decode_nxst_request(const struct ofp_header *oh, size_t length,
                             const struct ofputil_msg_type **typep)
 {
     const char *category = "Nicira extension statistics request";
@@ -426,7 +424,7 @@ ofputil_decode_nxst_request(const struct ofp_header *oh,
     const struct nicira_stats_msg *nsm;
     int error;
 
-    error = check_nxstats_msg(oh);
+    error = check_nxstats_msg(oh, length);
     if (error) {
         return error;
     }
@@ -447,7 +445,7 @@ ofputil_decode_nxst_request(const struct ofp_header *oh,
 }
 
 static int
-ofputil_decode_nxst_reply(const struct ofp_header *oh,
+ofputil_decode_nxst_reply(const struct ofp_header *oh, size_t length,
                           const struct ofputil_msg_type **typep)
 {
     const char *category = "Nicira extension statistics reply";
@@ -455,7 +453,7 @@ ofputil_decode_nxst_reply(const struct ofp_header *oh,
     const struct nicira_stats_msg *nsm;
     int error;
 
-    error = check_nxstats_msg(oh);
+    error = check_nxstats_msg(oh, length);
     if (error) {
         return error;
     }
@@ -476,10 +474,8 @@ ofputil_decode_nxst_reply(const struct ofp_header *oh,
 }
 
 static int
-check_stats_msg(const struct ofp_header *oh)
+check_stats_msg(size_t length)
 {
-    size_t length = ntohs(oh->length);
-
     if (length < sizeof(struct ofp_stats_msg)) {
         VLOG_WARN_RL(&bad_ofmsg_rl, "truncated stats message");
         return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
@@ -489,7 +485,7 @@ check_stats_msg(const struct ofp_header *oh)
 }
 
 static int
-ofputil_decode_ofpst_request(const struct ofp_header *oh,
+ofputil_decode_ofpst_request(const struct ofp_header *oh, size_t length,
                              const struct ofputil_msg_type **typep)
 {
     const char *category = "OpenFlow statistics";
@@ -497,7 +493,7 @@ ofputil_decode_ofpst_request(const struct ofp_header *oh,
     const struct ofputil_msg_type *type;
     int error;
 
-    error = check_stats_msg(oh);
+    error = check_stats_msg(length);
     if (error) {
         return error;
     }
@@ -511,7 +507,7 @@ ofputil_decode_ofpst_request(const struct ofp_header *oh,
         REQ_CASE(OFPST_QUEUE,     sizeof(struct ofp_queue_stats_request), 0);
 
     case OFPST_VENDOR:
-        return ofputil_decode_nxst_request(oh, typep);
+        return ofputil_decode_nxst_request(oh, length, typep);
 
     default:
         VLOG_WARN_RL(&bad_ofmsg_rl, "received %s of unknown type %"PRIu16,
@@ -524,7 +520,7 @@ ofputil_decode_ofpst_request(const struct ofp_header *oh,
 }
 
 static int
-ofputil_decode_ofpst_reply(const struct ofp_header *oh,
+ofputil_decode_ofpst_reply(const struct ofp_header *oh, size_t length,
                            const struct ofputil_msg_type **typep)
 {
     const char *category = "OpenFlow statistics";
@@ -532,7 +528,7 @@ ofputil_decode_ofpst_reply(const struct ofp_header *oh,
     const struct ofputil_msg_type *type;
     int error;
 
-    error = check_stats_msg(oh);
+    error = check_stats_msg(length);
     if (error) {
         return error;
     }
@@ -549,7 +545,7 @@ ofputil_decode_ofpst_reply(const struct ofp_header *oh,
                  sizeof(struct ofp_queue_stats));
 
     case OFPST_VENDOR:
-        return ofputil_decode_nxst_reply(oh, typep);
+        return ofputil_decode_nxst_reply(oh, length, typep);
 
     default:
         VLOG_WARN_RL(&bad_ofmsg_rl, "received %s of unknown type %"PRIu16,
@@ -562,7 +558,7 @@ ofputil_decode_ofpst_reply(const struct ofp_header *oh,
 }
 
 static int
-ofputil_decode_msg_type__(const struct ofp_header *oh,
+ofputil_decode_msg_type__(const struct ofp_header *oh, size_t length,
                           const struct ofputil_msg_type **typep)
 {
     const char *category = "OpenFlow message";
@@ -592,13 +588,13 @@ ofputil_decode_msg_type__(const struct ofp_header *oh,
         MSG_CASE(OFPT_BARRIER_REPLY,      sizeof(struct ofp_header), 0);
 
     case OFPT_STATS_REQUEST:
-        return ofputil_decode_ofpst_request(oh, typep);
+        return ofputil_decode_ofpst_request(oh, length, typep);
 
     case OFPT_STATS_REPLY:
-        return ofputil_decode_ofpst_reply(oh, typep);
+        return ofputil_decode_ofpst_reply(oh, length, typep);
 
     case OFPT_VENDOR:
-        return ofputil_decode_vendor(oh, typep);
+        return ofputil_decode_vendor(oh, length, typep);
 
     default:
         VLOG_WARN_RL(&bad_ofmsg_rl, "received %s of unknown type %"PRIu8,
@@ -610,7 +606,6 @@ ofputil_decode_msg_type__(const struct ofp_header *oh,
     return 0;
 }
 
-
 /* Decodes the message type represented by 'oh'.  Returns 0 if successful or
  * an OpenFlow error code constructed with ofp_mkerr() on failure.  Either
  * way, stores in '*typep' a type structure that can be inspected with the
@@ -625,17 +620,34 @@ int
 ofputil_decode_msg_type(const struct ofp_header *oh,
                         const struct ofputil_msg_type **typep)
 {
-    int error = ofputil_decode_msg_type__(oh, typep);
+    size_t length = ntohs(oh->length);
+    int error;
+
+    error = ofputil_decode_msg_type__(oh, length, typep);
     if (!error) {
-        error = ofputil_check_length(*typep, ntohs(oh->length));
+        error = ofputil_check_length(*typep, length);
     }
     if (error) {
-        static const struct ofputil_msg_type ofputil_invalid_type = {
-            OFPUTIL_MSG_INVALID,
-            0, "OFPUTIL_MSG_INVALID",
-            0, 0
-        };
+        *typep = &ofputil_invalid_type;
+    }
+    return error;
+}
+
+/* Decodes the message type represented by 'oh', of which only the first
+ * 'length' bytes are available.  Returns 0 if successful or an OpenFlow error
+ * code constructed with ofp_mkerr() on failure.  Either way, stores in
+ * '*typep' a type structure that can be inspected with the
+ * ofputil_msg_type_*() functions.  */
+int
+ofputil_decode_msg_type_partial(const struct ofp_header *oh, size_t length,
+                                const struct ofputil_msg_type **typep)
+{
+    int error;
 
+    error = (length >= sizeof *oh
+             ? ofputil_decode_msg_type__(oh, length, typep)
+             : ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN));
+    if (error) {
         *typep = &ofputil_invalid_type;
     }
     return error;
diff --git a/lib/ofp-util.h b/lib/ofp-util.h
index b110d71..02b85fc 100644
--- a/lib/ofp-util.h
+++ b/lib/ofp-util.h
@@ -90,6 +90,8 @@ enum ofputil_msg_code {
 struct ofputil_msg_type;
 int ofputil_decode_msg_type(const struct ofp_header *,
                             const struct ofputil_msg_type **);
+int ofputil_decode_msg_type_partial(const struct ofp_header *, size_t length,
+                                    const struct ofputil_msg_type **);
 enum ofputil_msg_code ofputil_msg_type_code(const struct ofputil_msg_type *);
 const char *ofputil_msg_type_name(const struct ofputil_msg_type *);
 int ofputil_check_output_port(uint16_t ofp_port, int max_ports);
-- 
1.7.4.4

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

Reply via email to