---
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
[email protected]
http://openvswitch.org/mailman/listinfo/dev