summaryrefslogtreecommitdiff
path: root/ofproto/ofproto.c
diff options
context:
space:
mode:
authorBen Pfaff <blp@ovn.org>2018-08-30 12:24:45 -0700
committerBen Pfaff <blp@ovn.org>2019-01-15 16:59:37 -0800
commitaf3c51aee409def94ad4b45870124164205b2ee9 (patch)
tree7a21672603df623a177254afb8ca6c681fa5e83b /ofproto/ofproto.c
parent4e413ac88d4841d7e17de3e36bba3fa12796e938 (diff)
downloadopenvswitch-af3c51aee409def94ad4b45870124164205b2ee9.tar.gz
ofproto: Handle flow monitor requests with multiple parts.
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.c89
1 files changed, 46 insertions, 43 deletions
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index d60decad8..d63d47625 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -6362,49 +6362,60 @@ flow_monitor_delete(struct ofconn *ofconn, uint32_t id)
}
static enum ofperr
-handle_flow_monitor_request(struct ofconn *ofconn, const struct ofp_header *oh)
+handle_flow_monitor_request(struct ofconn *ofconn, const struct ovs_list *msgs)
OVS_EXCLUDED(ofproto_mutex)
{
struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
- struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
-
struct ofmonitor **monitors = NULL;
size_t allocated_monitors = 0;
size_t n_monitors = 0;
- enum ofperr error;
-
ovs_mutex_lock(&ofproto_mutex);
- for (;;) {
- struct ofputil_flow_monitor_request request;
- struct ofmonitor *m;
- int retval;
+ struct ofpbuf *b;
+ LIST_FOR_EACH (b, list_node, msgs) {
+ for (;;) {
+ enum ofperr error;
- retval = ofputil_decode_flow_monitor_request(&request, &b);
- if (retval == EOF) {
- break;
- } else if (retval) {
- error = retval;
- goto error;
- }
+ struct ofputil_flow_monitor_request request;
+ int retval = ofputil_decode_flow_monitor_request(&request, b);
+ if (retval == EOF) {
+ break;
+ } else if (retval) {
+ error = retval;
+ goto error;
+ }
- if (request.table_id != 0xff
- && request.table_id >= ofproto->n_tables) {
- error = OFPERR_OFPBRC_BAD_TABLE_ID;
- goto error;
- }
+ if (request.table_id != OFPTT_ALL
+ && request.table_id >= ofproto->n_tables) {
+ error = OFPERR_OFPBRC_BAD_TABLE_ID;
+ goto error;
+ }
- error = ofmonitor_create(&request, ofconn, &m);
- if (error) {
- goto error;
- }
+ struct ofmonitor *m;
+ error = ofmonitor_create(&request, ofconn, &m);
+ if (error) {
+ goto error;
+ }
+
+ if (n_monitors >= allocated_monitors) {
+ monitors = x2nrealloc(monitors, &allocated_monitors,
+ sizeof *monitors);
+ }
+ monitors[n_monitors++] = m;
+ continue;
+
+ error:
+ ofconn_send_error(ofconn, b->data, error);
+
+ for (size_t i = 0; i < n_monitors; i++) {
+ ofmonitor_destroy(monitors[i]);
+ }
+ free(monitors);
+ ovs_mutex_unlock(&ofproto_mutex);
- if (n_monitors >= allocated_monitors) {
- monitors = x2nrealloc(monitors, &allocated_monitors,
- sizeof *monitors);
+ return error;
}
- monitors[n_monitors++] = m;
}
struct rule_collection rules;
@@ -6414,7 +6425,7 @@ handle_flow_monitor_request(struct ofconn *ofconn, const struct ofp_header *oh)
}
struct ovs_list replies;
- ofpmp_init(&replies, oh);
+ ofpmp_init(&replies, ofpbuf_from_list(ovs_list_back(msgs))->header);
ofmonitor_compose_refresh_updates(&rules, &replies);
ovs_mutex_unlock(&ofproto_mutex);
@@ -6424,15 +6435,6 @@ handle_flow_monitor_request(struct ofconn *ofconn, const struct ofp_header *oh)
free(monitors);
return 0;
-
-error:
- for (size_t i = 0; i < n_monitors; i++) {
- ofmonitor_destroy(monitors[i]);
- }
- free(monitors);
- ovs_mutex_unlock(&ofproto_mutex);
-
- return error;
}
static enum ofperr
@@ -8402,9 +8404,6 @@ handle_single_part_openflow(struct ofconn *ofconn, const struct ofp_header *oh,
case OFPTYPE_TABLE_STATS_REQUEST:
return handle_table_stats_request(ofconn, oh);
- case OFPTYPE_TABLE_FEATURES_STATS_REQUEST:
- OVS_NOT_REACHED();
-
case OFPTYPE_TABLE_DESC_REQUEST:
return handle_table_desc_request(ofconn, oh);
@@ -8417,8 +8416,10 @@ handle_single_part_openflow(struct ofconn *ofconn, const struct ofp_header *oh,
case OFPTYPE_PORT_DESC_STATS_REQUEST:
return handle_port_desc_stats_request(ofconn, oh);
+ case OFPTYPE_TABLE_FEATURES_STATS_REQUEST:
case OFPTYPE_FLOW_MONITOR_STATS_REQUEST:
- return handle_flow_monitor_request(ofconn, oh);
+ /* Handled as multipart requests in handle_openflow(). */
+ OVS_NOT_REACHED();
case OFPTYPE_METER_STATS_REQUEST:
case OFPTYPE_METER_CONFIG_STATS_REQUEST:
@@ -8516,6 +8517,8 @@ handle_openflow(struct ofconn *ofconn, const struct ovs_list *msgs)
if (!error) {
if (type == OFPTYPE_TABLE_FEATURES_STATS_REQUEST) {
handle_table_features_request(ofconn, msgs);
+ } else if (type == OFPTYPE_FLOW_MONITOR_STATS_REQUEST) {
+ handle_flow_monitor_request(ofconn, msgs);
} else if (!ovs_list_is_short(msgs)) {
error = OFPERR_OFPBRC_BAD_STAT;
} else {