--- 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