From: YAMAMOTO Takashi Date: Thu, 24 Oct 2013 03:07:43 +0000 (+0900) Subject: ofproto: Report correct errors for unsupported stats/multipart requests. X-Git-Tag: sliver-openvswitch-2.0.90-1~7^2~5 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=76ec08e01b4075b2e6d76ecbc5872513dd5b873f;p=sliver-openvswitch.git ofproto: Report correct errors for unsupported stats/multipart requests. The correct error in that case is OFPERR_OFPBRC_BAD_STAT, not OFPERR_OFPBRC_BAD_TYPE. Currently, the only example of unsupported stats/multipart request is OFPTYPE_TABLE_FEATURES_STATS_REQUEST. Signed-off-by: YAMAMOTO Takashi Signed-off-by: Ben Pfaff --- diff --git a/OPENFLOW-1.1+ b/OPENFLOW-1.1+ index bd6ced6bd..47cb60323 100644 --- a/OPENFLOW-1.1+ +++ b/OPENFLOW-1.1+ @@ -116,9 +116,6 @@ following additional work. (This is based on the change log at the end of the OF1.3 spec, reusing most of the section titles directly. I didn't compare the specs carefully yet.) - * Send errors for unsupported multipart requests. - [required for OF1.3+] - * Add support for multipart requests. [optional for OF1.3+] diff --git a/lib/ofp-msgs.c b/lib/ofp-msgs.c index d136f73d4..9f1b453b2 100644 --- a/lib/ofp-msgs.c +++ b/lib/ofp-msgs.c @@ -260,22 +260,48 @@ ofphdrs_decode_assert(struct ofphdrs *hdrs, } static bool -ofphdrs_is_stat(const struct ofphdrs *hdrs) +ofp_is_stat_request(enum ofp_version version, uint8_t type) { - switch ((enum ofp_version) hdrs->version) { + switch (version) { + case OFP10_VERSION: + return type == OFPT10_STATS_REQUEST; + case OFP11_VERSION: + case OFP12_VERSION: + case OFP13_VERSION: + return type == OFPT11_STATS_REQUEST; + } + + return false; +} + +static bool +ofp_is_stat_reply(enum ofp_version version, uint8_t type) +{ + switch (version) { case OFP10_VERSION: - return (hdrs->type == OFPT10_STATS_REQUEST || - hdrs->type == OFPT10_STATS_REPLY); + return type == OFPT10_STATS_REPLY; case OFP11_VERSION: case OFP12_VERSION: case OFP13_VERSION: - return (hdrs->type == OFPT11_STATS_REQUEST || - hdrs->type == OFPT11_STATS_REPLY); + return type == OFPT11_STATS_REPLY; } return false; } +static bool +ofp_is_stat(enum ofp_version version, uint8_t type) +{ + return (ofp_is_stat_request(version, type) || + ofp_is_stat_reply(version, type)); +} + +static bool +ofphdrs_is_stat(const struct ofphdrs *hdrs) +{ + return ofp_is_stat(hdrs->version, hdrs->type); +} + size_t ofphdrs_len(const struct ofphdrs *hdrs) { @@ -811,6 +837,13 @@ ofpmsg_body(const struct ofp_header *oh) ofphdrs_decode_assert(&hdrs, oh, ntohs(oh->length)); return (const uint8_t *) oh + ofphdrs_len(&hdrs); } + +/* Return if it's a stat/multipart (OFPST) request message. */ +bool +ofpmsg_is_stat_request(const struct ofp_header *oh) +{ + return ofp_is_stat_request(oh->version, oh->type); +} static ovs_be16 *ofpmp_flags__(const struct ofp_header *); diff --git a/lib/ofp-msgs.h b/lib/ofp-msgs.h index bfc84f3e6..aa19fe31f 100644 --- a/lib/ofp-msgs.h +++ b/lib/ofp-msgs.h @@ -584,6 +584,7 @@ enum ofptype ofptype_from_ofpraw(enum ofpraw); /* OpenFlow message properties. */ void ofpmsg_update_length(struct ofpbuf *); const void *ofpmsg_body(const struct ofp_header *); +bool ofpmsg_is_stat_request(const struct ofp_header *); /* Multipart messages (aka "statistics"). * diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 402b38d01..cb5bc735d 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -5790,7 +5790,7 @@ handle_openflow__(struct ofconn *ofconn, const struct ofpbuf *msg) /* FIXME: Change the following once they are implemented: */ case OFPTYPE_QUEUE_GET_CONFIG_REQUEST: case OFPTYPE_TABLE_FEATURES_STATS_REQUEST: - return OFPERR_OFPBRC_BAD_TYPE; + /* fallthrough */ case OFPTYPE_HELLO: case OFPTYPE_ERROR: @@ -5821,7 +5821,11 @@ handle_openflow__(struct ofconn *ofconn, const struct ofpbuf *msg) case OFPTYPE_METER_FEATURES_STATS_REPLY: case OFPTYPE_TABLE_FEATURES_STATS_REPLY: default: - return OFPERR_OFPBRC_BAD_TYPE; + if (ofpmsg_is_stat_request(oh)) { + return OFPERR_OFPBRC_BAD_STAT; + } else { + return OFPERR_OFPBRC_BAD_TYPE; + } } }