summaryrefslogtreecommitdiff
path: root/ofproto/ofproto.c
diff options
context:
space:
mode:
authorBen Pfaff <blp@ovn.org>2018-08-29 11:14:31 -0700
committerBen Pfaff <blp@ovn.org>2019-01-10 16:03:03 -0800
commitfd4b7a0ef1d25c4e37652ff6e60b7f492ba982de (patch)
treee42728656a0eeebb436e9bd8a4c52143c6e5140d /ofproto/ofproto.c
parentbe51cd41734336f3569bd7e18768123799b42a13 (diff)
downloadopenvswitch-fd4b7a0ef1d25c4e37652ff6e60b7f492ba982de.tar.gz
ofproto: Handle multipart requests with multiple parts.
OpenFlow has a concept of multipart messages, that is, messages that can be broken into multiple pieces that are sent separately. Before OpenFlow 1.3, only replies could actually have multiple pieces. OpenFlow 1.3 introduced the idea that requests could have multiple pieces. This is only useful for multipart requests that take an array as part of the request, which amounts to only flow monitoring requests and table features requests. So far, OVS hasn't implemented the multipart versions of these (it just reports an error). This commit introduces the necessary infastructure to implement them properly. Acked-by: Justin Pettit <jpettit@ovn.org> Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'ofproto/ofproto.c')
-rw-r--r--ofproto/ofproto.c41
1 files changed, 19 insertions, 22 deletions
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index dfcbc5499..bdc3ac684 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -258,7 +258,7 @@ static void delete_flows__(struct rule_collection *,
static void ofproto_group_delete_all__(struct ofproto *)
OVS_REQUIRES(ofproto_mutex);
static bool ofproto_group_exists(const struct ofproto *, uint32_t group_id);
-static void handle_openflow(struct ofconn *, const struct ofpbuf *);
+static void handle_openflow(struct ofconn *, const struct ovs_list *msgs);
static enum ofperr ofproto_flow_mod_init(struct ofproto *,
struct ofproto_flow_mod *,
const struct ofputil_flow_mod *fm,
@@ -8102,26 +8102,14 @@ handle_tlv_table_request(struct ofconn *ofconn, const struct ofp_header *oh)
return 0;
}
+/* Processes the single-part OpenFlow message 'oh' that was received on
+ * 'ofconn'. Returns an ofperr that, if nonzero, the caller should send back
+ * to the controller. */
static enum ofperr
-handle_openflow__(struct ofconn *ofconn, const struct ofpbuf *msg)
+handle_single_part_openflow(struct ofconn *ofconn, const struct ofp_header *oh,
+ enum ofptype type)
OVS_EXCLUDED(ofproto_mutex)
{
- const struct ofp_header *oh = msg->data;
- enum ofptype type;
- enum ofperr error;
-
- error = ofptype_decode(&type, oh);
- if (error) {
- return error;
- }
- if (oh->version >= OFP13_VERSION && ofpmsg_is_stat_request(oh)
- && ofpmp_more(oh)) {
- /* We have no buffer implementation for multipart requests.
- * Report overflow for requests which consists of multiple
- * messages. */
- return OFPERR_OFPBRC_MULTIPART_BUFFER_OVERFLOW;
- }
-
switch (type) {
/* OpenFlow requests. */
case OFPTYPE_ECHO_REQUEST:
@@ -8309,15 +8297,24 @@ handle_openflow__(struct ofconn *ofconn, const struct ofpbuf *msg)
}
static void
-handle_openflow(struct ofconn *ofconn, const struct ofpbuf *ofp_msg)
+handle_openflow(struct ofconn *ofconn, const struct ovs_list *msgs)
OVS_EXCLUDED(ofproto_mutex)
{
- enum ofperr error = handle_openflow__(ofconn, ofp_msg);
+ COVERAGE_INC(ofproto_recv_openflow);
+ struct ofpbuf *msg = ofpbuf_from_list(ovs_list_front(msgs));
+ enum ofptype type;
+ enum ofperr error = ofptype_decode(&type, msg->data);
+ if (!error) {
+ if (!ovs_list_is_short(msgs)) {
+ error = OFPERR_OFPBRC_BAD_STAT;
+ } else {
+ error = handle_single_part_openflow(ofconn, msg->data, type);
+ }
+ }
if (error) {
- ofconn_send_error(ofconn, ofp_msg->data, error);
+ ofconn_send_error(ofconn, msg->data, error);
}
- COVERAGE_INC(ofproto_recv_openflow);
}
static uint64_t