From patchwork Thu Aug 30 20:00:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Pfaff X-Patchwork-Id: 964170 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 421YNX18SDz9s1x for ; Fri, 31 Aug 2018 06:04:12 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 107B2CE9; Thu, 30 Aug 2018 20:01:19 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 78D85CDB for ; Thu, 30 Aug 2018 20:01:18 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [217.70.183.200]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 696927DE for ; Thu, 30 Aug 2018 20:01:17 +0000 (UTC) X-Originating-IP: 173.228.112.177 Received: from sigabrt.gateway.sonic.net (173-228-112-177.dsl.dynamic.fusionbroadband.com [173.228.112.177]) (Authenticated sender: blp@ovn.org) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id 2FE4120005; Thu, 30 Aug 2018 20:01:14 +0000 (UTC) From: Ben Pfaff To: dev@openvswitch.org Date: Thu, 30 Aug 2018 13:00:56 -0700 Message-Id: <20180830200056.15484-8-blp@ovn.org> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180830200056.15484-1-blp@ovn.org> References: <20180830200056.15484-1-blp@ovn.org> X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Ben Pfaff Subject: [ovs-dev] [PATCH 8/8] ofproto: Handle flow monitor requests with multiple parts. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org Signed-off-by: Ben Pfaff Acked-by: Justin Pettit --- ofproto/ofproto.c | 84 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 44 insertions(+), 40 deletions(-) diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index d65a3fea1559..54f56d9f100e 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -6344,49 +6344,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 != 0xff + && 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); + 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); + + return error; } - monitors[n_monitors++] = m; } struct rule_collection rules; @@ -6396,7 +6407,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); @@ -6406,15 +6417,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 @@ -8398,7 +8400,7 @@ handle_single_part_openflow(struct ofconn *ofconn, const struct ofp_header *oh, return handle_port_desc_stats_request(ofconn, oh); case OFPTYPE_FLOW_MONITOR_STATS_REQUEST: - return handle_flow_monitor_request(ofconn, oh); + OVS_NOT_REACHED(); case OFPTYPE_METER_STATS_REQUEST: case OFPTYPE_METER_CONFIG_STATS_REQUEST: @@ -8496,6 +8498,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 {