From patchwork Fri Jun 1 17:41:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 924258 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=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="tTgQntFL"; dkim-atps=neutral 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 40yBWC0FtTz9ry1 for ; Sat, 2 Jun 2018 03:43:02 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id B6D2FEC4; Fri, 1 Jun 2018 17:42:36 +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 4B8E5E60 for ; Fri, 1 Jun 2018 17:42:35 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg0-f66.google.com (mail-pg0-f66.google.com [74.125.83.66]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 3F065136 for ; Fri, 1 Jun 2018 17:42:34 +0000 (UTC) Received: by mail-pg0-f66.google.com with SMTP id p9-v6so11559847pgc.9 for ; Fri, 01 Jun 2018 10:42:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xiLFgJ+B4ntw7t3cxmrOqE8Jj9uSJA3q+nDs7JdnAW8=; b=tTgQntFLPK+MDeVwRuqZnOWjzTsI28MVsGJ2zCSneehLvBuH2lLP4Wl/YkZHaAt6ZC MPF8tbcIqf1oiBTVo0A62by62XgVH29wG59/y8ekeMjfkfpkXIsryqI9H6/DGNVFGEHt 90a6qJsCN4dGMMH7GFAVILmjDIriUCr7bUZ7fG6AVCpIrBmLKPmpHDxgTl0jhq/Frc4k 3NbO22dqrET/LcneIV94GznX2uRo/wZT6AsY1zkuIr34EGqXmVAzqKDVyR9LOoIXgd7z 8ZX56KuEMlsOx9dOXqbMW6bKcEXThRib/btvSsGMyB1KqKbzDNrfNwYeFmssRscqCOI2 maKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=xiLFgJ+B4ntw7t3cxmrOqE8Jj9uSJA3q+nDs7JdnAW8=; b=M3CHdHCrFgIAHeeBBhAGpLOeCEcPtLELRKJ4l6NflNbASdK+DgNIryGce9eyoZxTuU mN/CSDopJCjf2dioTL3raP+xjrRd6piqP1ehWp0E2j0p0tBnYoxnl7vj5uXUWSdA0Vrn vVQso6dITvl5GIy7IPZhLELGZWN/JNnGoh0yzActvRwcFthQmSJDPSDEbY4bZ2hDMPGy YNGTvjC0HnXJMPq9WYLFiWFzr6COgNl2tKVXy+pO7q6jx77xX/tNktGkiZ40RLSvi8GC EMXokpOfU+9MNWrnmlmweDQD7Fz40Vy/W9HTQXFsa4gMXqJ14waZ7kh0VZwB2xh//MyU giAw== X-Gm-Message-State: ALKqPwehHXHAmTUvXaQKd6wb2Ogdlw0Q2j6ymN6Wf9PMZaV2sEiS34OD mWCXlmNlrpZMMMatbF99L/gqww== X-Google-Smtp-Source: ADUXVKLXft9Qg0l1C43nyv+birttx1sw0aCZ+qzqIlc6015C6oXP1Roui6nnYlujUzUersRQfnE+AA== X-Received: by 2002:a65:4b02:: with SMTP id r2-v6mr9527712pgq.82.1527874953475; Fri, 01 Jun 2018 10:42:33 -0700 (PDT) Received: from localhost.localdomain.localdomain (c-73-162-150-77.hsd1.ca.comcast.net. [73.162.150.77]) by smtp.gmail.com with ESMTPSA id v26-v6sm9600279pfe.13.2018.06.01.10.42.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 Jun 2018 10:42:32 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Fri, 1 Jun 2018 10:41:51 -0700 Message-Id: <1527874926-40450-2-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> References: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v3 01/16] ovn-controller: Incremental processing engine 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 This patch implements the engine which will be used in future patches for ovn-controller incremental processing. Signed-off-by: Han Zhou --- ovn/lib/automake.mk | 4 +- ovn/lib/inc-proc-eng.c | 141 ++++++++++++++++++++++++++++++++++ ovn/lib/inc-proc-eng.h | 202 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 346 insertions(+), 1 deletion(-) create mode 100644 ovn/lib/inc-proc-eng.c create mode 100644 ovn/lib/inc-proc-eng.h diff --git a/ovn/lib/automake.mk b/ovn/lib/automake.mk index 6178fc2..c1d37c5 100644 --- a/ovn/lib/automake.mk +++ b/ovn/lib/automake.mk @@ -17,7 +17,9 @@ ovn_lib_libovn_la_SOURCES = \ ovn/lib/ovn-util.c \ ovn/lib/ovn-util.h \ ovn/lib/logical-fields.c \ - ovn/lib/logical-fields.h + ovn/lib/logical-fields.h \ + ovn/lib/inc-proc-eng.c \ + ovn/lib/inc-proc-eng.h nodist_ovn_lib_libovn_la_SOURCES = \ ovn/lib/ovn-nb-idl.c \ ovn/lib/ovn-nb-idl.h \ diff --git a/ovn/lib/inc-proc-eng.c b/ovn/lib/inc-proc-eng.c new file mode 100644 index 0000000..8006acd --- /dev/null +++ b/ovn/lib/inc-proc-eng.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2018 eBay Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include +#include +#include + +#include "openvswitch/dynamic-string.h" +#include "openvswitch/hmap.h" +#include "openvswitch/vlog.h" +#include "inc-proc-eng.h" + +VLOG_DEFINE_THIS_MODULE(inc_proc_eng); + +static bool engine_force_recompute = false; + +void +engine_set_force_recompute(bool val) +{ + engine_force_recompute = val; +} + +void +engine_init(struct engine_node *node) +{ + for (size_t i = 0; i < node->n_inputs; i++) { + engine_init(node->inputs[i].node); + } + if (node->init) { + node->init(node); + } +} + +void +engine_cleanup(struct engine_node *node) +{ + for (size_t i = 0; i < node->n_inputs; i++) { + engine_cleanup(node->inputs[i].node); + } + if (node->cleanup) { + node->cleanup(node); + } +} + +struct engine_node * +engine_get_input(const char *input_name, struct engine_node *node) +{ + size_t i; + for (i = 0; i < node->n_inputs; i++) { + if (!strcmp(node->inputs[i].node->name, input_name)) { + return node->inputs[i].node; + } + } + return NULL; +} + +void +engine_add_input(struct engine_node *node, struct engine_node *input, + bool (*change_handler)(struct engine_node *)) +{ + ovs_assert(node->n_inputs < ENGINE_MAX_INPUT); + node->inputs[node->n_inputs].node = input; + node->inputs[node->n_inputs].change_handler = change_handler; + node->n_inputs ++; +} + +void +engine_run(struct engine_node *node, uint64_t run_id) +{ + if (node->run_id == run_id) { + return; + } + node->run_id = run_id; + + node->changed = false; + if (!node->n_inputs) { + node->run(node); + VLOG_DBG("node: %s, changed: %d", node->name, node->changed); + return; + } + + for (size_t i = 0; i < node->n_inputs; i++) { + engine_run(node->inputs[i].node, run_id); + } + + bool need_compute = false; + bool need_recompute = false; + + if (engine_force_recompute) { + need_recompute = true; + } else { + for (size_t i = 0; i < node->n_inputs; i++) { + if (node->inputs[i].node->changed) { + need_compute = true; + if (!node->inputs[i].change_handler) { + need_recompute = true; + break; + } + } + } + } + + if (need_recompute) { + VLOG_DBG("node: %s, recompute (%s)", node->name, + engine_force_recompute ? "forced" : "triggered"); + node->run(node); + } else if (need_compute) { + for (size_t i = 0; i < node->n_inputs; i++) { + if (node->inputs[i].node->changed) { + VLOG_DBG("node: %s, handle change for input %s", + node->name, node->inputs[i].node->name); + if (!node->inputs[i].change_handler(node)) { + VLOG_DBG("node: %s, can't handle change for input %s, " + "fall back to recompute", + node->name, node->inputs[i].node->name); + node->run(node); + break; + } + } + } + } + + VLOG_DBG("node: %s, changed: %d", node->name, node->changed); +} diff --git a/ovn/lib/inc-proc-eng.h b/ovn/lib/inc-proc-eng.h new file mode 100644 index 0000000..8399321 --- /dev/null +++ b/ovn/lib/inc-proc-eng.h @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2018 eBay Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INC_PROC_ENG_H +#define INC_PROC_ENG_H 1 + +/* The Incremental Processing Engine is a framework for incrementally + * processing changes from different inputs. The main user is ovn-controller. + * To compute desired states (e.g. openflow rules) based on many inputs (e.g. + * south-bound DB tables, local OVSDB interfaces, etc.), it is straightforward + * to recompute everything when there is any change in any inputs, but it + * is inefficient when the size of the input data becomes large. Instead, + * tracking the changes and update the desired states based on what's changed + * is more efficient and scalable. However, it is not straightforward to + * implement the change-based processing when there are a big number of + * inputs. In addition, what makes it more complicated is that intermediate + * results needs to be computed, which needs to be reused in different part + * of the processing and finally generates the final desired states. It is + * proved to be difficult and error-prone to implement this kind of complex + * processing by ad-hoc implementation. + * + * This framework is to provide a generic way to solve the above problem. + * It does not understand the processing logic, but provides a unified way + * to describe the inputs and dependencies clearly, with interfaces for + * users to implement the processing logic for how to handle each input + * changes. + * + * The engine is composed of engine_nodes. Each engine_node is either + * an input, an output or both (intermediate result). Each engine node + * maintains its own data, which is persistent across interactions. Each node + * has zero to ENGINE_MAX_INPUT inputs, which creates a DAG (directed + * acyclic graph). For each input of each engine_node, there is a + * change_handler to process changes of that input, and update the data + * of the engine_node. Then the user can simply call the run() method + * of the engine so that the processing will happen in the order according + * to the dependencies defined and handle the changes incrementally. + * + * While the more fine-grained dependencies and change-handlers are + * implemented, the more efficient the processing will be, it is not + * realistic to implement all change-processing for all inputs (and + * intermediate results). The engine doesn't require change-handler to be + * implemented for every input of every node. Users can choose to implement + * the most important change-handlers (for the changes happens most + * frequently) for overall performance. When there is no change_handler + * defined for a certain input on a certain engine_node, the run() method + * of the engine_node will be called to fall-back to a full recompute + * against all its inputs. + */ + +#define ENGINE_MAX_INPUT 256 + +struct engine_node; + +struct engine_node_input { + /* The input node. */ + struct engine_node *node; + + /* Change handler for changes of the input node. The changes may need to be + * evaluated against all the other inputs. Returns: + * - true: if change can be handled + * - false: if change cannot be handled (indicating full recompute needed) + */ + bool (*change_handler)(struct engine_node *node); +}; + +struct engine_node { + /* A unique id to distinguish each iteration of the engine_run(). */ + uint64_t run_id; + + /* A unique name for each node. */ + char *name; + + /* Number of inputs of this node. */ + size_t n_inputs; + + /* Inputs of this node. */ + struct engine_node_input inputs[ENGINE_MAX_INPUT]; + + /* Data of this node. It is vague and interpreted by the related functions. + * The content of the data should be changed only by the change_handlers + * and run() function of the current node. Users should ensure that the + * data is read-only in change-handlers of the nodes that depends on this + * node. */ + void *data; + + /* Whether the data changed in the last engine run. */ + bool changed; + + /* Context data for the engine processing, such as OVSDB IDLs. */ + void *context; + + /* Method to initialize data. It may be NULL. */ + void (*init)(struct engine_node *); + + /* Method to clean up data. It may be NULL. */ + void (*cleanup)(struct engine_node *); + + /* Fully processes all inputs of this node and regenerates the data + * of this node */ + void (*run)(struct engine_node *); +}; + +/* Initialize the data for the engine nodes recursively. It calls each node's + * init() method if not NULL. It should be called before the main loop. */ +void engine_init(struct engine_node *); + +/* Execute the processing recursively, which should be called in the main + * loop. */ +void engine_run(struct engine_node *, uint64_t run_id); + +/* Clean up the data for the engine nodes recursively. It calls each node's + * cleanup() method if not NULL. It should be called before the program + * terminates. */ +void engine_cleanup(struct engine_node *); + +/* Get the input node with for */ +struct engine_node * engine_get_input(const char *input_name, + struct engine_node *); + +/* Add an input (dependency) for , with corresponding change_handler, + * which can be NULL. If the change_handler is NULL, the engine will not + * be able to process the change incrementally, and will fall back to call + * the run method to recompute. */ +void engine_add_input(struct engine_node *node, struct engine_node *input, + bool (*change_handler)(struct engine_node *)); + +/* Force the engine to recompute everything if set to true. It is used + * in circumstances when we are not sure there is change or not, or + * when there is change but the engine couldn't be executed in that + * iteration, and the change can't be tracked across iterations */ +void engine_set_force_recompute(bool val); + +/* Macro to define an engine node. */ +#define ENGINE_NODE(NAME, NAME_STR, CTX) \ + struct engine_node en_##NAME = { \ + .name = NAME_STR, \ + .data = &ed_##NAME, \ + .context = CTX, \ + .init = en_##NAME##_init, \ + .run = en_##NAME##_run, \ + .cleanup = en_##NAME##_cleanup, \ + }; + +/* Macro to define member functions of an engine node which represents + * a table of OVSDB */ +#define ENGINE_FUNC_OVSDB(DB_NAME, TBL_NAME, IDL) \ +static void \ +en_##DB_NAME##_##TBL_NAME##_run(struct engine_node *node) \ +{ \ + static bool first_run = true; \ + if (first_run) { \ + first_run = false; \ + node->changed = true; \ + return; \ + } \ + struct controller_ctx *ctx = (struct controller_ctx *)node->context; \ + if (DB_NAME##rec_##TBL_NAME##_track_get_first(ctx->IDL)) { \ + node->changed = true; \ + return; \ + } \ + node->changed = false; \ +} \ +static void (*en_##DB_NAME##_##TBL_NAME##_init)(struct engine_node *node) \ + = NULL; \ +static void (*en_##DB_NAME##_##TBL_NAME##_cleanup)(struct engine_node *node) \ + = NULL; + +/* Macro to define member functions of an engine node which represents + * a table of OVN SB DB */ +#define ENGINE_FUNC_SB(TBL_NAME) \ + ENGINE_FUNC_OVSDB(sb, TBL_NAME, ovnsb_idl) + +/* Macro to define member functions of an engine node which represents + * a table of open_vswitch DB */ +#define ENGINE_FUNC_OVS(TBL_NAME) \ + ENGINE_FUNC_OVSDB(ovs, TBL_NAME, ovs_idl) + +/* Macro to define an engine node which represents a table of OVN SB DB */ +#define ENGINE_NODE_SB(TBL_NAME, TBL_NAME_STR, CTX) \ + void *ed_sb_##TBL_NAME; \ + ENGINE_NODE(sb_##TBL_NAME, TBL_NAME_STR, CTX) + +/* Macro to define an engine node which represents a table of open_vswitch + * DB */ +#define ENGINE_NODE_OVS(TBL_NAME, TBL_NAME_STR, CTX) \ + void *ed_ovs_##TBL_NAME; \ + ENGINE_NODE(ovs_##TBL_NAME, TBL_NAME_STR, CTX) + +#endif /* ovn/lib/inc-proc-eng.h */ From patchwork Fri Jun 1 17:41:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 924259 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=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="hZwb7qUa"; dkim-atps=neutral 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 40yBWt5gPtz9ry1 for ; Sat, 2 Jun 2018 03:43:38 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id F2DCBEEF; Fri, 1 Jun 2018 17:42:40 +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 8FA66E60 for ; Fri, 1 Jun 2018 17:42:39 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg0-f65.google.com (mail-pg0-f65.google.com [74.125.83.65]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 0668BCF for ; Fri, 1 Jun 2018 17:42:38 +0000 (UTC) Received: by mail-pg0-f65.google.com with SMTP id e11-v6so2380752pgq.0 for ; Fri, 01 Jun 2018 10:42:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=RN8pddBpzV5lMijRLyCJAgs3IQEpMujBc4TaXbGgMqM=; b=hZwb7qUaANs02dUQQqLFLGvyVeSECJwk6d8rvPyU0TEJA/FDyoMhb5auCPHWFoOWzn RYv7dwhkAyaIkW/Xlz+ihN4+6BH1cZMagPxQOymqjUMPTOc2DtJEFXgAqFsc8CacpZNF dacZH3gqYIowt8ZK768+5Ln62xggupxmwSf9f9/bgMeQIR/ME7vMk/x9a7hzLTzDfeFc GfefkNYB/NLd4OS6cSzqqlh1+3g6kZduA9Iv8SJY0TbYDEh5AhlhtaaPJy4vndBT9D+U I57rGEcQNQf7ZxIC8rAcYMZlh56BVukl1eFnYl586fXpIX+J2fOPdzK4lZ67ivKgq1LY TtMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=RN8pddBpzV5lMijRLyCJAgs3IQEpMujBc4TaXbGgMqM=; b=czlXMjM6iu/Dan0WUXEP1wmgOUHwl/WtNIxqiI0VuJLvie2IuLeGXsMF8HJWfdBjVh o9RhLYEeDq/lvq9VFq3S5CziHTqXFL1c3uBWukyiZOP7B4nm0kaOb7DKwI9cUMLG/mVk 0GtCpJSYBaRsVFh2A6F0vXO9zolN567Dkhjv1D3yNgZTeVR/VnXklTNoniQTMjO0ymxe MzjkMmSKjsXAI9l11yEhUXpUMWq9OV4/m9CU6ZKB/H8W5eOwqHtdizKuROQDqdDCdOXJ zZSMZI2b2mG1jLemccwW1onato/kTUyeRNroSHo4jlsa49mfAdo9DieFZksM10SzIn78 rlkA== X-Gm-Message-State: ALKqPwelGrXUttH9QOQUuXds5PfkOmUOh2BZ6Q4/baCBJxkDJ2V/7HQ3 jesKIJt7kq/IS21dKQ0YkLXYlw== X-Google-Smtp-Source: ADUXVKLz+PaM0OuGpywbanqn95HgvCT9ZQ6Ecg9/7e6mvRhsgmj/3ROTT4kv+xfl069+DLfRGLTQSg== X-Received: by 2002:a62:ff1d:: with SMTP id b29-v6mr11873530pfn.181.1527874958440; Fri, 01 Jun 2018 10:42:38 -0700 (PDT) Received: from localhost.localdomain.localdomain (c-73-162-150-77.hsd1.ca.comcast.net. [73.162.150.77]) by smtp.gmail.com with ESMTPSA id v26-v6sm9600279pfe.13.2018.06.01.10.42.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 Jun 2018 10:42:38 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Fri, 1 Jun 2018 10:41:52 -0700 Message-Id: <1527874926-40450-3-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> References: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v3 02/16] ovn-controller: Track OVSDB changes 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 Track OVSDB changes for future patches of incremental processing Signed-off-by: Han Zhou --- ovn/controller/bfd.c | 4 ++-- ovn/controller/binding.c | 16 ++++++++-------- ovn/controller/encaps.c | 12 ++++++------ ovn/controller/ovn-controller.c | 22 +++++++++++++--------- ovn/controller/physical.c | 12 ++++++------ 5 files changed, 35 insertions(+), 31 deletions(-) diff --git a/ovn/controller/bfd.c b/ovn/controller/bfd.c index 8f020d5..d7ea9e8 100644 --- a/ovn/controller/bfd.c +++ b/ovn/controller/bfd.c @@ -34,8 +34,8 @@ bfd_register_ovs_idl(struct ovsdb_idl *ovs_idl) { /* NOTE: this assumes that binding.c has added the * ovsrec_interface table */ - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_bfd); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_bfd_status); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_bfd); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_bfd_status); } diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c index 0785a94..84ff4d6 100644 --- a/ovn/controller/binding.c +++ b/ovn/controller/binding.c @@ -53,16 +53,16 @@ binding_register_ovs_idl(struct ovsdb_idl *ovs_idl) ovsdb_idl_add_column(ovs_idl, &ovsrec_bridge_col_ports); ovsdb_idl_add_table(ovs_idl, &ovsrec_table_port); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_name); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_interfaces); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_qos); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_name); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_interfaces); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_qos); ovsdb_idl_add_table(ovs_idl, &ovsrec_table_interface); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_name); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_external_ids); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_bfd); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_bfd_status); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_status); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_name); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_external_ids); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_bfd); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_bfd_status); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_status); ovsdb_idl_add_table(ovs_idl, &ovsrec_table_qos); ovsdb_idl_add_column(ovs_idl, &ovsrec_qos_col_type); diff --git a/ovn/controller/encaps.c b/ovn/controller/encaps.c index f187a8f..9f33394 100644 --- a/ovn/controller/encaps.c +++ b/ovn/controller/encaps.c @@ -32,13 +32,13 @@ encaps_register_ovs_idl(struct ovsdb_idl *ovs_idl) ovsdb_idl_add_table(ovs_idl, &ovsrec_table_bridge); ovsdb_idl_add_column(ovs_idl, &ovsrec_bridge_col_ports); ovsdb_idl_add_table(ovs_idl, &ovsrec_table_port); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_name); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_interfaces); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_external_ids); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_name); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_interfaces); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_external_ids); ovsdb_idl_add_table(ovs_idl, &ovsrec_table_interface); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_name); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_type); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_options); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_name); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_type); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_options); } /* Enough context to create a new tunnel, using tunnel_add(). */ diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 86e1836..d4cc69f 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -520,16 +520,16 @@ ctrl_register_ovs_idl(struct ovsdb_idl *ovs_idl) ovsdb_idl_add_column(ovs_idl, &ovsrec_open_vswitch_col_external_ids); ovsdb_idl_add_column(ovs_idl, &ovsrec_open_vswitch_col_bridges); ovsdb_idl_add_table(ovs_idl, &ovsrec_table_interface); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_name); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_bfd); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_bfd_status); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_type); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_options); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_ofport); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_name); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_bfd); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_bfd_status); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_type); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_options); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_ofport); ovsdb_idl_add_table(ovs_idl, &ovsrec_table_port); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_name); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_interfaces); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_external_ids); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_name); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_interfaces); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_external_ids); ovsdb_idl_add_table(ovs_idl, &ovsrec_table_bridge); ovsdb_idl_add_column(ovs_idl, &ovsrec_bridge_col_ports); ovsdb_idl_add_column(ovs_idl, &ovsrec_bridge_col_name); @@ -638,6 +638,7 @@ main(int argc, char *argv[]) create_ovnsb_indexes(ovnsb_idl_loop.idl); lport_init(ovnsb_idl_loop.idl); + ovsdb_idl_track_add_all(ovnsb_idl_loop.idl); ovsdb_idl_omit_alert(ovnsb_idl_loop.idl, &sbrec_chassis_col_nb_cfg); update_sb_monitors(ovnsb_idl_loop.idl, NULL, NULL, NULL); ovsdb_idl_get_initial_snapshot(ovnsb_idl_loop.idl); @@ -833,6 +834,9 @@ main(int argc, char *argv[]) } } } + + ovsdb_idl_track_clear(ctx.ovnsb_idl); + ovsdb_idl_track_clear(ctx.ovs_idl); poll_block(); if (should_service_stop()) { exiting = true; diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c index fc8adcf..b3aa27a 100644 --- a/ovn/controller/physical.c +++ b/ovn/controller/physical.c @@ -51,14 +51,14 @@ physical_register_ovs_idl(struct ovsdb_idl *ovs_idl) ovsdb_idl_add_column(ovs_idl, &ovsrec_bridge_col_ports); ovsdb_idl_add_table(ovs_idl, &ovsrec_table_port); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_name); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_interfaces); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_external_ids); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_name); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_interfaces); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_external_ids); ovsdb_idl_add_table(ovs_idl, &ovsrec_table_interface); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_name); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_ofport); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_external_ids); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_name); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_ofport); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_external_ids); } static struct simap localvif_to_ofport = From patchwork Fri Jun 1 17:41:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 924261 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=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="HSzHmHXd"; dkim-atps=neutral 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 40yBXy3V89z9ry1 for ; Sat, 2 Jun 2018 03:44:34 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id B26B7EF7; Fri, 1 Jun 2018 17:42:45 +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 ECE04EF9 for ; Fri, 1 Jun 2018 17:42:42 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f48.google.com (mail-pl0-f48.google.com [209.85.160.48]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 850D66B7 for ; Fri, 1 Jun 2018 17:42:41 +0000 (UTC) Received: by mail-pl0-f48.google.com with SMTP id n10-v6so15714862plp.0 for ; Fri, 01 Jun 2018 10:42:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=edBKvjjQ+AtrUP73QXxTElElNp833Hf1573oOrBhtPw=; b=HSzHmHXdSRHibV8MnjMWH8CjaDYdIRoRsFIAXGtzQ7FEGZuUr1aW2UX0mS1qjEy1pf WzLQrdZYN9TYnQplSNoz6x6suOQYf65ArFVi4r5S/LlpBBUa4f6tbwieT3mEXY3i4D7C K3Gmq7Rxzg32JeM8PSCGIjBgulEGjuDIJO1SntDDnL0NCzSXzwh7U0ni84F/uUmuHM8+ l9lUD1QN1yVA12JFP/IgLQuywl+m+5J6QvhrQN8pGzbytXL3YzhokB/MtPtnO51euHYA YKHDFl+KztySUaaWUTG0yOjdKtgkt4waKOR7WVyvmhalENj0O+eHRULEtbU2BGMiOSLz 0dMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=edBKvjjQ+AtrUP73QXxTElElNp833Hf1573oOrBhtPw=; b=dXrt7IVu+swIARw0sEvo5hH3RT9I3AQ88S6+ndRvf8L5gGj8tr4fCHpovWxWNpdMMf qvV/R+/as+Z0B8zJRwxM1drpYXoiKA0t35InKqxraqxOVHR81QVHRniNUPh/94vBmRyP UN39s8u0ORuU37WTGHonuiQaUkYremXvn7wku4AqGRXiMFKimalTxmDEKVXV5FHKpGmp bGWQ0bllmV4ySLSNx+2PzSmu+eH5HdSOkQugOwwARhExaSIowO6vOhDR4CpdEN6z/G6b xPgI5z6kA1MmQslqsx1xebKb1iqhIZS08iqVpV8I++MYLF1SpprXNTgltmluk0D9oojP hcIg== X-Gm-Message-State: ALKqPwfcemZtg2FzsTylbPI52y18E5e1OEbSj9Klno21icTv1ET+WoxG MTTKCFAk0vHAkJktybmHv9ukXA== X-Google-Smtp-Source: ADUXVKJlLg6jxboawSeO1TCITT59RCTEdULKUEkj9lMCznS41uRUwrqSlY8ABfte96MbhLXW53PncQ== X-Received: by 2002:a17:902:7d85:: with SMTP id a5-v6mr11936041plm.356.1527874960281; Fri, 01 Jun 2018 10:42:40 -0700 (PDT) Received: from localhost.localdomain.localdomain (c-73-162-150-77.hsd1.ca.comcast.net. [73.162.150.77]) by smtp.gmail.com with ESMTPSA id v26-v6sm9600279pfe.13.2018.06.01.10.42.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 Jun 2018 10:42:39 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Fri, 1 Jun 2018 10:41:53 -0700 Message-Id: <1527874926-40450-4-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> References: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v3 03/16] ovn-controller: Initial use of incremental engine in main 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 Incremental proccessing engine is used to compute flows. In this patch we only create 2 engine nodes with simple dependency: runtime_data -> flow_output In each iteration everything is still recomputed. Signed-off-by: Han Zhou --- ovn/controller/ofctrl.c | 21 +- ovn/controller/ofctrl.h | 5 +- ovn/controller/ovn-controller.c | 481 ++++++++++++++++++++++++++-------------- 3 files changed, 337 insertions(+), 170 deletions(-) diff --git a/ovn/controller/ofctrl.c b/ovn/controller/ofctrl.c index 349de3a..134f0e5 100644 --- a/ovn/controller/ofctrl.c +++ b/ovn/controller/ofctrl.c @@ -477,11 +477,21 @@ recv_S_UPDATE_FLOWS(const struct ofp_header *oh, enum ofptype type, } } + +enum mf_field_id +ofctrl_get_mf_field_id(void) +{ + if (!rconn_is_connected(swconn)) { + return 0; + } + return (state == S_CLEAR_FLOWS || state == S_UPDATE_FLOWS + ? mff_ovn_geneve : 0); +} + /* Runs the OpenFlow state machine against 'br_int', which is local to the * hypervisor on which we are running. Attempts to negotiate a Geneve option - * field for class OVN_GENEVE_CLASS, type OVN_GENEVE_TYPE. If successful, - * returns the MFF_* field ID for the option, otherwise returns 0. */ -enum mf_field_id + * field for class OVN_GENEVE_CLASS, type OVN_GENEVE_TYPE. */ +void ofctrl_run(const struct ovsrec_bridge *br_int, struct shash *pending_ct_zones) { char *target = xasprintf("unix:%s/%s.mgmt", ovs_rundir(), br_int->name); @@ -494,7 +504,7 @@ ofctrl_run(const struct ovsrec_bridge *br_int, struct shash *pending_ct_zones) rconn_run(swconn); if (!rconn_is_connected(swconn)) { - return 0; + return; } if (seqno != rconn_get_connection_seqno(swconn)) { seqno = rconn_get_connection_seqno(swconn); @@ -557,9 +567,6 @@ ofctrl_run(const struct ovsrec_bridge *br_int, struct shash *pending_ct_zones) * point, so ensure that we come back again without waiting. */ poll_immediate_wake(); } - - return (state == S_CLEAR_FLOWS || state == S_UPDATE_FLOWS - ? mff_ovn_geneve : 0); } void diff --git a/ovn/controller/ofctrl.h b/ovn/controller/ofctrl.h index a8b3afc..45081e5 100644 --- a/ovn/controller/ofctrl.h +++ b/ovn/controller/ofctrl.h @@ -33,8 +33,9 @@ struct shash; /* Interface for OVN main loop. */ void ofctrl_init(struct ovn_extend_table *group_table, struct ovn_extend_table *meter_table); -enum mf_field_id ofctrl_run(const struct ovsrec_bridge *br_int, - struct shash *pending_ct_zones); +void ofctrl_run(const struct ovsrec_bridge *br_int, + struct shash *pending_ct_zones); +enum mf_field_id ofctrl_get_mf_field_id(void); bool ofctrl_can_put(void); void ofctrl_put(struct hmap *flow_table, struct shash *pending_ct_zones, int64_t nb_cfg); diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index d4cc69f..91e0293 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -60,6 +60,7 @@ #include "timeval.h" #include "timer.h" #include "stopwatch.h" +#include "ovn/lib/inc-proc-eng.h" VLOG_DEFINE_THIS_MODULE(main); @@ -208,15 +209,26 @@ update_sb_monitors(struct ovsdb_idl *ovnsb_idl, ovsdb_idl_condition_destroy(&dns); } +static const char * +br_int_name(const struct ovsrec_open_vswitch *cfg) +{ + return smap_get_def(&cfg->external_ids, "ovn-bridge", DEFAULT_BRIDGE_NAME); +} + static const struct ovsrec_bridge * -create_br_int(struct controller_ctx *ctx, - const struct ovsrec_open_vswitch *cfg, - const char *bridge_name) +create_br_int(struct controller_ctx *ctx) { if (!ctx->ovs_idl_txn) { return NULL; } + const struct ovsrec_open_vswitch *cfg; + cfg = ovsrec_open_vswitch_first(ctx->ovs_idl); + if (!cfg) { + return NULL; + } + const char *bridge_name = br_int_name(cfg); + ovsdb_idl_txn_add_comment(ctx->ovs_idl_txn, "ovn-controller: creating integration bridge '%s'", bridge_name); @@ -259,15 +271,7 @@ get_br_int(struct controller_ctx *ctx) return NULL; } - const char *br_int_name = smap_get_def(&cfg->external_ids, "ovn-bridge", - DEFAULT_BRIDGE_NAME); - - const struct ovsrec_bridge *br; - br = get_bridge(ctx->ovs_idl, br_int_name); - if (!br) { - return create_br_int(ctx, cfg, br_int_name); - } - return br; + return get_bridge(ctx->ovs_idl, br_int_name(cfg)); } static const char * @@ -476,11 +480,8 @@ restore_ct_zones(struct ovsdb_idl *ovs_idl, return; } - const char *br_int_name = smap_get_def(&cfg->external_ids, "ovn-bridge", - DEFAULT_BRIDGE_NAME); - const struct ovsrec_bridge *br_int; - br_int = get_bridge(ovs_idl, br_int_name); + br_int = get_bridge(ovs_idl, br_int_name(cfg)); if (!br_int) { /* If the integration bridge hasn't been defined, assume that * any existing ct-zone definitions aren't valid. */ @@ -588,6 +589,227 @@ create_ovnsb_indexes(struct ovsdb_idl *ovnsb_idl) OVSDB_INDEX_ASC, NULL); } +struct ed_type_runtime_data { + struct chassis_index chassis_index; + + /* Contains "struct local_datapath" nodes. */ + struct hmap local_datapaths; + + /* Contains the name of each logical port resident on the local + * hypervisor. These logical ports include the VIFs (and their child + * logical ports, if any) that belong to VMs running on the hypervisor, + * l2gateway ports for which options:l2gateway-chassis designates the + * local hypervisor, and localnet ports. */ + struct sset local_lports; + + /* Contains the same ports as local_lports, but in the format: + * _ */ + struct sset local_lport_ids; + struct sset active_tunnels; + struct shash addr_sets; + struct shash port_groups; + + /* connection tracking zones. */ + unsigned long ct_zone_bitmap[BITMAP_N_LONGS(MAX_CT_ZONES)]; + struct shash pending_ct_zones; + struct simap ct_zones; +}; + +static void +en_runtime_data_init(struct engine_node *node) +{ + struct controller_ctx *ctx = (struct controller_ctx *)node->context; + struct ed_type_runtime_data *data = + (struct ed_type_runtime_data *)node->data; + hmap_init(&data->local_datapaths); + sset_init(&data->local_lports); + sset_init(&data->local_lport_ids); + sset_init(&data->active_tunnels); + shash_init(&data->addr_sets); + shash_init(&data->port_groups); + shash_init(&data->pending_ct_zones); + simap_init(&data->ct_zones); + + /* Initialize connection tracking zones. */ + memset(data->ct_zone_bitmap, 0, sizeof data->ct_zone_bitmap); + bitmap_set1(data->ct_zone_bitmap, 0); /* Zone 0 is reserved. */ + restore_ct_zones(ctx->ovs_idl, &data->ct_zones, data->ct_zone_bitmap); +} + +static void +en_runtime_data_cleanup(struct engine_node *node) +{ + struct ed_type_runtime_data *data = + (struct ed_type_runtime_data *)node->data; + + expr_const_sets_destroy(&data->addr_sets); + shash_destroy(&data->addr_sets); + expr_const_sets_destroy(&data->port_groups); + shash_destroy(&data->port_groups); + + chassis_index_destroy(&data->chassis_index); + + sset_destroy(&data->local_lports); + sset_destroy(&data->local_lport_ids); + sset_destroy(&data->active_tunnels); + struct local_datapath *cur_node, *next_node; + HMAP_FOR_EACH_SAFE (cur_node, next_node, hmap_node, + &data->local_datapaths) { + free(cur_node->peer_dps); + hmap_remove(&data->local_datapaths, &cur_node->hmap_node); + free(cur_node); + } + hmap_destroy(&data->local_datapaths); + + simap_destroy(&data->ct_zones); + shash_destroy(&data->pending_ct_zones); +} + +static void +en_runtime_data_run(struct engine_node *node) +{ + struct controller_ctx *ctx = (struct controller_ctx *)node->context; + struct ed_type_runtime_data *data = + (struct ed_type_runtime_data *)node->data; + struct hmap *local_datapaths = &data->local_datapaths; + struct sset *local_lports = &data->local_lports; + struct sset *local_lport_ids = &data->local_lport_ids; + struct sset *active_tunnels = &data->active_tunnels; + struct chassis_index *chassis_index = &data->chassis_index; + struct shash *addr_sets = &data->addr_sets; + struct shash *port_groups = &data->port_groups; + unsigned long *ct_zone_bitmap = data->ct_zone_bitmap; + struct shash *pending_ct_zones = &data->pending_ct_zones; + struct simap *ct_zones = &data->ct_zones; + + static bool first_run = true; + if (first_run) { + /* don't cleanup since there is no data yet */ + first_run = false; + } else { + struct local_datapath *cur_node, *next_node; + HMAP_FOR_EACH_SAFE (cur_node, next_node, hmap_node, local_datapaths) { + free(cur_node->peer_dps); + hmap_remove(local_datapaths, &cur_node->hmap_node); + free(cur_node); + } + hmap_clear(local_datapaths); + sset_destroy(local_lports); + sset_destroy(local_lport_ids); + sset_destroy(active_tunnels); + chassis_index_destroy(chassis_index); + expr_const_sets_destroy(addr_sets); + expr_const_sets_destroy(port_groups); + sset_init(local_lports); + sset_init(local_lport_ids); + sset_init(active_tunnels); + } + + const char *chassis_id = get_chassis_id(ctx->ovs_idl); + const struct ovsrec_bridge *br_int = get_br_int(ctx); + + ovs_assert(br_int && chassis_id); + const struct sbrec_chassis *chassis = NULL; + chassis = get_chassis(ctx->ovnsb_idl, chassis_id); + ovs_assert(chassis); + + chassis_index_init(chassis_index, ctx->ovnsb_idl); + bfd_calculate_active_tunnels(br_int, active_tunnels); + binding_run(ctx, br_int, chassis, + chassis_index, active_tunnels, local_datapaths, + local_lports, local_lport_ids); + + addr_sets_init(ctx, addr_sets); + port_groups_init(ctx, port_groups); + update_ct_zones(local_lports, local_datapaths, ct_zones, + ct_zone_bitmap, pending_ct_zones); + + node->changed = true; +} + +struct ed_type_flow_output { + /* desired flows */ + struct hmap flow_table; + /* group ids for load balancing */ + struct ovn_extend_table group_table; + /* meter ids for QoS */ + struct ovn_extend_table meter_table; +}; + +static void +en_flow_output_init(struct engine_node *node) +{ + struct ed_type_flow_output *data = + (struct ed_type_flow_output *)node->data; + hmap_init(&data->flow_table); + ovn_extend_table_init(&data->group_table); + ovn_extend_table_init(&data->meter_table); +} + +static void +en_flow_output_cleanup(struct engine_node *node) +{ + struct ed_type_flow_output *data = + (struct ed_type_flow_output *)node->data; + hmap_destroy(&data->flow_table); + ovn_extend_table_destroy(&data->group_table); + ovn_extend_table_destroy(&data->meter_table); +} + +static void +en_flow_output_run(struct engine_node *node) +{ + struct controller_ctx *ctx = (struct controller_ctx *)node->context; + struct ed_type_runtime_data *rt_data = + (struct ed_type_runtime_data *)engine_get_input( + "runtime_data", node)->data; + struct hmap *local_datapaths = &rt_data->local_datapaths; + struct sset *local_lports = &rt_data->local_lports; + struct sset *local_lport_ids = &rt_data->local_lport_ids; + struct sset *active_tunnels = &rt_data->active_tunnels; + struct chassis_index *chassis_index = &rt_data->chassis_index; + struct shash *addr_sets = &rt_data->addr_sets; + struct shash *port_groups = &rt_data->port_groups; + struct simap *ct_zones = &rt_data->ct_zones; + + const struct ovsrec_bridge *br_int = get_br_int(ctx); + + const char *chassis_id = get_chassis_id(ctx->ovs_idl); + + const struct sbrec_chassis *chassis = NULL; + if (chassis_id) { + chassis = get_chassis(ctx->ovnsb_idl, chassis_id); + } + + ovs_assert(br_int && chassis); + + struct ed_type_flow_output *fo = + (struct ed_type_flow_output *)node->data; + struct hmap *flow_table = &fo->flow_table; + struct ovn_extend_table *group_table = &fo->group_table; + struct ovn_extend_table *meter_table = &fo->meter_table; + + static bool first_run = true; + if (first_run) { + first_run = false; + } else { + hmap_clear(flow_table); + } + + lflow_run(ctx, chassis, + chassis_index, local_datapaths, group_table, + meter_table, addr_sets, port_groups, flow_table, + active_tunnels, local_lport_ids); + + enum mf_field_id mff_ovn_geneve = ofctrl_get_mf_field_id(); + + physical_run(ctx, mff_ovn_geneve, + br_int, chassis, ct_zones, + flow_table, local_datapaths, local_lports, + chassis_index, active_tunnels); + node->changed = true; +} + int main(int argc, char *argv[]) { @@ -609,17 +831,9 @@ main(int argc, char *argv[]) } unixctl_command_register("exit", "", 0, 0, ovn_controller_exit, &exiting); - /* Initialize group ids for loadbalancing. */ - struct ovn_extend_table group_table; - ovn_extend_table_init(&group_table); - - /* Initialize meter ids for QoS. */ - struct ovn_extend_table meter_table; - ovn_extend_table_init(&meter_table); daemonize_complete(); - ofctrl_init(&group_table, &meter_table); pinctrl_init(); lflow_init(); @@ -643,21 +857,32 @@ main(int argc, char *argv[]) update_sb_monitors(ovnsb_idl_loop.idl, NULL, NULL, NULL); ovsdb_idl_get_initial_snapshot(ovnsb_idl_loop.idl); - /* Initialize connection tracking zones. */ - struct simap ct_zones = SIMAP_INITIALIZER(&ct_zones); - struct shash pending_ct_zones = SHASH_INITIALIZER(&pending_ct_zones); - unsigned long ct_zone_bitmap[BITMAP_N_LONGS(MAX_CT_ZONES)]; - memset(ct_zone_bitmap, 0, sizeof ct_zone_bitmap); - bitmap_set1(ct_zone_bitmap, 0); /* Zone 0 is reserved. */ - restore_ct_zones(ovs_idl_loop.idl, &ct_zones, ct_zone_bitmap); + + stopwatch_create(CONTROLLER_LOOP_STOPWATCH_NAME, SW_MS); + + struct controller_ctx ctx = { + .ovs_idl = ovs_idl_loop.idl, + .ovnsb_idl = ovnsb_idl_loop.idl + }; + struct ed_type_runtime_data ed_runtime_data; + struct ed_type_flow_output ed_flow_output; + + ENGINE_NODE(runtime_data, "runtime_data", &ctx); + ENGINE_NODE(flow_output, "flow_output", &ctx); + + engine_add_input(&en_flow_output, &en_runtime_data, NULL); + engine_init(&en_flow_output); + + ofctrl_init(&ed_flow_output.group_table, + &ed_flow_output.meter_table); unixctl_command_register("ct-zone-list", "", 0, 0, - ct_zone_list, &ct_zones); + ct_zone_list, &ed_runtime_data.ct_zones); struct pending_pkt pending_pkt = { .conn = NULL }; unixctl_command_register("inject-pkt", "MICROFLOW", 1, 1, inject_pkt, &pending_pkt); - stopwatch_create(CONTROLLER_LOOP_STOPWATCH_NAME, SW_MS); + uint64_t engine_run_id = 0; /* Main loop. */ exiting = false; while (!exiting) { @@ -671,145 +896,82 @@ main(int argc, char *argv[]) free(new_ovnsb_remote); } - struct controller_ctx ctx = { - .ovs_idl = ovs_idl_loop.idl, - .ovs_idl_txn = ovsdb_idl_loop_run(&ovs_idl_loop), - .ovnsb_idl = ovnsb_idl_loop.idl, - .ovnsb_idl_txn = ovsdb_idl_loop_run(&ovnsb_idl_loop), - }; + ctx.ovs_idl = ovs_idl_loop.idl; + ctx.ovs_idl_txn = ovsdb_idl_loop_run(&ovs_idl_loop); + ctx.ovnsb_idl = ovnsb_idl_loop.idl; + ctx.ovnsb_idl_txn = ovsdb_idl_loop_run(&ovnsb_idl_loop); update_probe_interval(&ctx, ovnsb_remote); update_ssl_config(ctx.ovs_idl); - /* Contains "struct local_datapath" nodes. */ - struct hmap local_datapaths = HMAP_INITIALIZER(&local_datapaths); - - /* Contains the name of each logical port resident on the local - * hypervisor. These logical ports include the VIFs (and their child - * logical ports, if any) that belong to VMs running on the hypervisor, - * l2gateway ports for which options:l2gateway-chassis designates the - * local hypervisor, and localnet ports. */ - struct sset local_lports = SSET_INITIALIZER(&local_lports); - /* Contains the same ports as local_lports, but in the format: - * _ */ - struct sset local_lport_ids = SSET_INITIALIZER(&local_lport_ids); - struct sset active_tunnels = SSET_INITIALIZER(&active_tunnels); - const struct ovsrec_bridge *br_int = get_br_int(&ctx); + if (!br_int) { + br_int = create_br_int(&ctx); + } const char *chassis_id = get_chassis_id(ctx.ovs_idl); + const struct sbrec_chassis *chassis + = chassis_id ? chassis_run(&ctx, chassis_id, br_int) : NULL; - struct chassis_index chassis_index; - - chassis_index_init(&chassis_index, ctx.ovnsb_idl); - - const struct sbrec_chassis *chassis = NULL; - if (chassis_id) { - chassis = chassis_run(&ctx, chassis_id, br_int); - encaps_run(&ctx, br_int, chassis_id); - bfd_calculate_active_tunnels(br_int, &active_tunnels); - binding_run(&ctx, br_int, chassis, - &chassis_index, &active_tunnels, &local_datapaths, - &local_lports, &local_lport_ids); - } if (br_int && chassis) { - struct shash addr_sets = SHASH_INITIALIZER(&addr_sets); - addr_sets_init(&ctx, &addr_sets); - struct shash port_groups = SHASH_INITIALIZER(&port_groups); - port_groups_init(&ctx, &port_groups); - + ofctrl_run(br_int, &ed_runtime_data.pending_ct_zones); patch_run(&ctx, br_int, chassis); + encaps_run(&ctx, br_int, chassis_id); - enum mf_field_id mff_ovn_geneve = ofctrl_run(br_int, - &pending_ct_zones); - - pinctrl_run(&ctx, br_int, chassis, &chassis_index, - &local_datapaths, &active_tunnels); - update_ct_zones(&local_lports, &local_datapaths, &ct_zones, - ct_zone_bitmap, &pending_ct_zones); - if (ctx.ovs_idl_txn) { - if (ofctrl_can_put()) { - stopwatch_start(CONTROLLER_LOOP_STOPWATCH_NAME, - time_msec()); - - commit_ct_zones(br_int, &pending_ct_zones); - - struct hmap flow_table = HMAP_INITIALIZER(&flow_table); - lflow_run(&ctx, chassis, - &chassis_index, &local_datapaths, &group_table, - &meter_table, &addr_sets, &port_groups, - &flow_table, &active_tunnels, &local_lport_ids); - - if (chassis_id) { - bfd_run(&ctx, br_int, chassis, &local_datapaths, - &chassis_index); - } - physical_run(&ctx, mff_ovn_geneve, - br_int, chassis, &ct_zones, - &flow_table, &local_datapaths, &local_lports, - &chassis_index, &active_tunnels); - - stopwatch_stop(CONTROLLER_LOOP_STOPWATCH_NAME, - time_msec()); - - ofctrl_put(&flow_table, &pending_ct_zones, - get_nb_cfg(ctx.ovnsb_idl)); - - hmap_destroy(&flow_table); - } - if (ctx.ovnsb_idl_txn) { - int64_t cur_cfg = ofctrl_get_cur_cfg(); - if (cur_cfg && cur_cfg != chassis->nb_cfg) { - sbrec_chassis_set_nb_cfg(chassis, cur_cfg); - } + if (ofctrl_can_put()) { + stopwatch_start(CONTROLLER_LOOP_STOPWATCH_NAME, + time_msec()); + engine_run(&en_flow_output, ++engine_run_id); + stopwatch_stop(CONTROLLER_LOOP_STOPWATCH_NAME, + time_msec()); + + if (ctx.ovs_idl_txn) { + commit_ct_zones(br_int, &ed_runtime_data.pending_ct_zones); + bfd_run(&ctx, br_int, chassis, + &ed_runtime_data.local_datapaths, + &ed_runtime_data.chassis_index); } + ofctrl_put(&ed_flow_output.flow_table, + &ed_runtime_data.pending_ct_zones, + get_nb_cfg(ctx.ovnsb_idl)); + } + pinctrl_run(&ctx, br_int, chassis, &ed_runtime_data.chassis_index, + &ed_runtime_data.local_datapaths, + &ed_runtime_data.active_tunnels); + + update_sb_monitors(ctx.ovnsb_idl, chassis, + &ed_runtime_data.local_lports, + &ed_runtime_data.local_datapaths); + + } + + if (ctx.ovnsb_idl_txn) { + int64_t cur_cfg = ofctrl_get_cur_cfg(); + if (cur_cfg && cur_cfg != chassis->nb_cfg) { + sbrec_chassis_set_nb_cfg(chassis, cur_cfg); } + } - if (pending_pkt.conn) { + + if (pending_pkt.conn) { + if (br_int && chassis) { char *error = ofctrl_inject_pkt(br_int, pending_pkt.flow_s, - &port_groups, &addr_sets); + &ed_runtime_data.port_groups, + &ed_runtime_data.addr_sets); if (error) { unixctl_command_reply_error(pending_pkt.conn, error); free(error); } else { unixctl_command_reply(pending_pkt.conn, NULL); } - pending_pkt.conn = NULL; - free(pending_pkt.flow_s); + } else { + unixctl_command_reply_error(pending_pkt.conn, + "ovn-controller not ready."); } - - update_sb_monitors(ctx.ovnsb_idl, chassis, - &local_lports, &local_datapaths); - - expr_const_sets_destroy(&addr_sets); - shash_destroy(&addr_sets); - expr_const_sets_destroy(&port_groups); - shash_destroy(&port_groups); - } - - /* If we haven't handled the pending packet insertion - * request, the system is not ready. */ - if (pending_pkt.conn) { - unixctl_command_reply_error(pending_pkt.conn, - "ovn-controller not ready."); pending_pkt.conn = NULL; free(pending_pkt.flow_s); } - chassis_index_destroy(&chassis_index); - - sset_destroy(&local_lports); - sset_destroy(&local_lport_ids); - sset_destroy(&active_tunnels); - - struct local_datapath *cur_node, *next_node; - HMAP_FOR_EACH_SAFE (cur_node, next_node, hmap_node, &local_datapaths) { - free(cur_node->peer_dps); - hmap_remove(&local_datapaths, &cur_node->hmap_node); - free(cur_node); - } - hmap_destroy(&local_datapaths); - unixctl_server_run(unixctl); unixctl_server_wait(unixctl); @@ -826,10 +988,11 @@ main(int argc, char *argv[]) if (ovsdb_idl_loop_commit_and_wait(&ovs_idl_loop) == 1) { struct shash_node *iter, *iter_next; - SHASH_FOR_EACH_SAFE(iter, iter_next, &pending_ct_zones) { + SHASH_FOR_EACH_SAFE (iter, iter_next, + &ed_runtime_data.pending_ct_zones) { struct ct_zone_pending_entry *ctzpe = iter->data; if (ctzpe->state == CT_ZONE_DB_SENT) { - shash_delete(&pending_ct_zones, iter); + shash_delete(&ed_runtime_data.pending_ct_zones, iter); free(ctzpe); } } @@ -843,26 +1006,28 @@ main(int argc, char *argv[]) } } + engine_cleanup(&en_flow_output); + /* It's time to exit. Clean up the databases. */ bool done = false; while (!done) { - struct controller_ctx ctx = { + struct controller_ctx ctx_ = { .ovs_idl = ovs_idl_loop.idl, .ovs_idl_txn = ovsdb_idl_loop_run(&ovs_idl_loop), .ovnsb_idl = ovnsb_idl_loop.idl, .ovnsb_idl_txn = ovsdb_idl_loop_run(&ovnsb_idl_loop), }; - const struct ovsrec_bridge *br_int = get_br_int(&ctx); - const char *chassis_id = get_chassis_id(ctx.ovs_idl); + const struct ovsrec_bridge *br_int = get_br_int(&ctx_); + const char *chassis_id = get_chassis_id(ctx_.ovs_idl); const struct sbrec_chassis *chassis - = chassis_id ? get_chassis(ctx.ovnsb_idl, chassis_id) : NULL; + = chassis_id ? get_chassis(ctx_.ovnsb_idl, chassis_id) : NULL; /* Run all of the cleanup functions, even if one of them returns false. * We're done if all of them return true. */ - done = binding_cleanup(&ctx, chassis); - done = chassis_cleanup(&ctx, chassis) && done; - done = encaps_cleanup(&ctx, br_int) && done; + done = binding_cleanup(&ctx_, chassis); + done = chassis_cleanup(&ctx_, chassis) && done; + done = encaps_cleanup(&ctx_, br_int) && done; if (done) { poll_immediate_wake(); } @@ -877,12 +1042,6 @@ main(int argc, char *argv[]) ofctrl_destroy(); pinctrl_destroy(); - simap_destroy(&ct_zones); - shash_destroy(&pending_ct_zones); - - ovn_extend_table_destroy(&group_table); - ovn_extend_table_destroy(&meter_table); - ovsdb_idl_loop_destroy(&ovs_idl_loop); ovsdb_idl_loop_destroy(&ovnsb_idl_loop); From patchwork Fri Jun 1 17:41:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 924260 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=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="dWzkSAKA"; dkim-atps=neutral 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 40yBXQ45DPz9ry1 for ; Sat, 2 Jun 2018 03:44:06 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 166ABF13; Fri, 1 Jun 2018 17:42:44 +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 B7F01EF1 for ; Fri, 1 Jun 2018 17:42:42 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f67.google.com (mail-pl0-f67.google.com [209.85.160.67]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id BD2346D6 for ; Fri, 1 Jun 2018 17:42:41 +0000 (UTC) Received: by mail-pl0-f67.google.com with SMTP id n10-v6so15714867plp.0 for ; Fri, 01 Jun 2018 10:42:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=AS1Ft0R6iJ0USXgk4PQP6Wy24CsDN1HpDTjiTuK3KWE=; b=dWzkSAKAhN/xD7N3Tl5VcKe080udcJmMOQYsFKpSsz/ImT3xHQTzYfOHyrgPav6eVe BaFBRK4fL2nfZVAmJUpyxxneOKU/8BVYJ3x6bg3DIVM4e7o64TP5wvZjFnbn+qjD9V6a vZJq2HxM2zwSYjLWQ046CZOYNNAKWuOvNF5BLzKXSdIyFp6UGA4dKRwEJD0hOEn2NGu6 1U8pU4l4GFtfXA2OAp7jiIlAu0CYgMUv0sAOYyZ22ruRVRPeDKwmO5DfIYxABYOvgJRm GlAA/zFRE+OG9NPFGQsTg8ylwhIyYl4LQWPsF5VPkJmVczPym0jxLBfxGLpXd3lyOimT pNlg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=AS1Ft0R6iJ0USXgk4PQP6Wy24CsDN1HpDTjiTuK3KWE=; b=rIeAXLi2ha0r9y995GW51ELSbFKfXJYYhAiaiECE5YBqmq4833ay2i0tbrmmqDslVk tItU9qJWWD+oVIrfqey43aWRAZzpeV2P+lMYbAJ9Ev+hNcm8Dqiw7qwr43XIChegHn01 q+mhCtttOERmLOZmBQ3M15hlYUHiG3Uf9jLdHrB4Oz9JAS7zarqO5ZyPR52ex9leb31D ip+dOFckX/YXAMFczW8OpHM4YlCMh6r8qsDa5S0DNb1OPfDVy+wwoIXJxZVIezlzyvUk vs4KaoRVjYzDVMYT2qh7BY1DQX4F/CuR9pyHYZ5cRvI7meDFwm8cIcvHWZXnkSf2cDbR 7Ksw== X-Gm-Message-State: ALKqPwfqj7j9E+D+c6LFwSfBNV+Rp6MfCShJIlgcF/H2zoA/0cS3ayiO 8eWYu6Hh2hh8qvG2wcU3fp9tSw== X-Google-Smtp-Source: ADUXVKJDTYcB8+ixtYGdmv2t9/BYNCeq5oDNLZJ3WuWQHKQRNuT5ikJDnfqcIMEpVDojlCuPEqXuzQ== X-Received: by 2002:a17:902:5709:: with SMTP id k9-v6mr11776805pli.165.1527874961089; Fri, 01 Jun 2018 10:42:41 -0700 (PDT) Received: from localhost.localdomain.localdomain (c-73-162-150-77.hsd1.ca.comcast.net. [73.162.150.77]) by smtp.gmail.com with ESMTPSA id v26-v6sm9600279pfe.13.2018.06.01.10.42.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 Jun 2018 10:42:40 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Fri, 1 Jun 2018 10:41:54 -0700 Message-Id: <1527874926-40450-5-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> References: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v3 04/16] ovn-controller: Split SB inputs as separate incremental engine nodes 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 This patch expands the incremental processing by spliting SB inputs from runtime_data and add them as input for flow_output. Signed-off-by: Han Zhou --- ovn/controller/ovn-controller.c | 44 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 91e0293..63b797f 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -589,6 +589,20 @@ create_ovnsb_indexes(struct ovsdb_idl *ovnsb_idl) OVSDB_INDEX_ASC, NULL); } +ENGINE_FUNC_SB(chassis); +ENGINE_FUNC_SB(encap); +ENGINE_FUNC_SB(address_set); +ENGINE_FUNC_SB(port_group); +ENGINE_FUNC_SB(multicast_group); +ENGINE_FUNC_SB(datapath_binding); +ENGINE_FUNC_SB(port_binding); +ENGINE_FUNC_SB(mac_binding); +ENGINE_FUNC_SB(logical_flow); +ENGINE_FUNC_SB(dhcp_options); +ENGINE_FUNC_SB(dhcpv6_options); +ENGINE_FUNC_SB(dns); +ENGINE_FUNC_SB(gateway_chassis); + struct ed_type_runtime_data { struct chassis_index chassis_index; @@ -867,10 +881,38 @@ main(int argc, char *argv[]) struct ed_type_runtime_data ed_runtime_data; struct ed_type_flow_output ed_flow_output; + ENGINE_NODE_SB(chassis, "chassis", &ctx); + ENGINE_NODE_SB(encap, "encap", &ctx); + ENGINE_NODE_SB(address_set, "address_set", &ctx); + ENGINE_NODE_SB(port_group, "port_group", &ctx); + ENGINE_NODE_SB(multicast_group, "multicast_group", &ctx); + ENGINE_NODE_SB(datapath_binding, "datapath_binding", &ctx); + ENGINE_NODE_SB(port_binding, "port_binding", &ctx); + ENGINE_NODE_SB(mac_binding, "mac_binding", &ctx); + ENGINE_NODE_SB(logical_flow, "logical_flow", &ctx); + ENGINE_NODE_SB(dhcp_options, "dhcp_options", &ctx); + ENGINE_NODE_SB(dhcpv6_options, "dhcpv6_options", &ctx); + ENGINE_NODE_SB(dns, "dns", &ctx); + ENGINE_NODE_SB(gateway_chassis, "gateway_chassis", &ctx); + ENGINE_NODE(runtime_data, "runtime_data", &ctx); ENGINE_NODE(flow_output, "flow_output", &ctx); - engine_add_input(&en_flow_output, &en_runtime_data, NULL); + + engine_add_input(&en_flow_output, &en_sb_chassis, NULL); + engine_add_input(&en_flow_output, &en_sb_encap, NULL); + engine_add_input(&en_flow_output, &en_sb_address_set, NULL); + engine_add_input(&en_flow_output, &en_sb_port_group, NULL); + engine_add_input(&en_flow_output, &en_sb_multicast_group, NULL); + engine_add_input(&en_flow_output, &en_sb_datapath_binding, NULL); + engine_add_input(&en_flow_output, &en_sb_port_binding, NULL); + engine_add_input(&en_flow_output, &en_sb_mac_binding, NULL); + engine_add_input(&en_flow_output, &en_sb_logical_flow, NULL); + engine_add_input(&en_flow_output, &en_sb_dhcp_options, NULL); + engine_add_input(&en_flow_output, &en_sb_dhcpv6_options, NULL); + engine_add_input(&en_flow_output, &en_sb_dns, NULL); + engine_add_input(&en_flow_output, &en_sb_gateway_chassis, NULL); + engine_init(&en_flow_output); ofctrl_init(&ed_flow_output.group_table, From patchwork Fri Jun 1 17:41:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 924262 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=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="InqYcHrd"; dkim-atps=neutral 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 40yBYY3TFdz9ry1 for ; Sat, 2 Jun 2018 03:45:05 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 54606F26; Fri, 1 Jun 2018 17:42:47 +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 4E59EEFB for ; Fri, 1 Jun 2018 17:42:43 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f46.google.com (mail-pl0-f46.google.com [209.85.160.46]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id E27136D6 for ; Fri, 1 Jun 2018 17:42:42 +0000 (UTC) Received: by mail-pl0-f46.google.com with SMTP id u6-v6so15722232pls.9 for ; Fri, 01 Jun 2018 10:42:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=rU38yneEvjwW+JON6EyfbKqUw2zxFsIn/x9tFEq/u5k=; b=InqYcHrdT3EAbgeLzGTKH9JSlson0ZP0fatLVfKVlEIeaE8UMZ7Q0fTaY/l1+k83vD RrKQYhzkIiUJi50F1BVDpH72vdDElYQH4QZ8u3UU3Wl8PcCrY6B7o/5ADjb4ziJDDjGi tp47+eQBIalTVcodR80g8pink1y+0ffJPusPcubptE90tD1lL8jE7e2rSaxry2DdMBkH Bvxi48zXucTWLXZ6SnDvIub0IrNgL2011j4abppmhlu44mbv0J6eQXNpskpctSKMmroX PtEZJr/k/BB4G4WJL+aDPouTi4/zGhmXgEeEgrv9sInZpPtTjBuhbOx0HO1JxTJ7ewEX dcFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=rU38yneEvjwW+JON6EyfbKqUw2zxFsIn/x9tFEq/u5k=; b=Tk8R1+JYi8NGYdm17BhmdfDWVwXTatPXpoB6yVlXsiW2KcMTQjSkR9FPjwRjO59YYJ jb1l98h0F/lGTqf160AVjRtEZntP5IP57i8ESjDUiBdWRjv9t6PFveAes6VfIcjlZZeP zyESXYBWUTvXc8U4ku6haUFrz+QQvPUGo/q5NJJdbVvIXYB8S85+nguKQcnDWZG1XRmL 7OY3W8SkTJJfzEk59wk3heNVOMiU+RU8rXEdv6x/dl4dKoFY+nYZ1jpI2eS8mO+qAbQM MAlYRT+5nHRhLEBOBzSqy9gPBmUJMejrCm2cBvDVvijyYusOgj6zWGnRkaeSXcbjJ4a7 KQTQ== X-Gm-Message-State: ALKqPwfrp/nBwUzrVz+sipTUiEFptSIklgaSK5JAaloBNJxwfWfM/MNs K7VeYDoTPlFYYKz8EykwWiWHAg== X-Google-Smtp-Source: ADUXVKLjWsVJS3KSeJO2MafdMlxdiy6udFGCu2DJcBc/1PqR35+ff96hC4ohQmvfH4FSTy0o5fDsdw== X-Received: by 2002:a17:902:9689:: with SMTP id n9-v6mr11776235plp.363.1527874962317; Fri, 01 Jun 2018 10:42:42 -0700 (PDT) Received: from localhost.localdomain.localdomain (c-73-162-150-77.hsd1.ca.comcast.net. [73.162.150.77]) by smtp.gmail.com with ESMTPSA id v26-v6sm9600279pfe.13.2018.06.01.10.42.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 Jun 2018 10:42:41 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Fri, 1 Jun 2018 10:41:55 -0700 Message-Id: <1527874926-40450-6-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> References: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v3 05/16] ovn-controller: split ovs_idl inputs in incremental engine 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 Create nodes for ovs_idl inputs and add ovs_idl inputs and SB inputs as dependencies for runtime_data. With this patch there is no recomputed if there is no change in input. For example, pinctrl input will not trigger flow recompute any more. Signed-off-by: Han Zhou --- ovn/controller/ovn-controller.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 63b797f..e390afd 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -603,6 +603,9 @@ ENGINE_FUNC_SB(dhcpv6_options); ENGINE_FUNC_SB(dns); ENGINE_FUNC_SB(gateway_chassis); +ENGINE_FUNC_OVS(port); +ENGINE_FUNC_OVS(interface); + struct ed_type_runtime_data { struct chassis_index chassis_index; @@ -729,6 +732,7 @@ en_runtime_data_run(struct engine_node *node) chassis_index_init(chassis_index, ctx->ovnsb_idl); bfd_calculate_active_tunnels(br_int, active_tunnels); + /* requires ctx->ovnsb_idl_txn */ binding_run(ctx, br_int, chassis, chassis_index, active_tunnels, local_datapaths, local_lports, local_lport_ids); @@ -895,10 +899,16 @@ main(int argc, char *argv[]) ENGINE_NODE_SB(dns, "dns", &ctx); ENGINE_NODE_SB(gateway_chassis, "gateway_chassis", &ctx); + ENGINE_NODE_OVS(port, "ovs_table_port", &ctx); + ENGINE_NODE_OVS(interface, "ovs_table_interface", &ctx); + ENGINE_NODE(runtime_data, "runtime_data", &ctx); ENGINE_NODE(flow_output, "flow_output", &ctx); engine_add_input(&en_flow_output, &en_runtime_data, NULL); + engine_add_input(&en_flow_output, &en_ovs_port, NULL); + engine_add_input(&en_flow_output, &en_ovs_interface, NULL); + engine_add_input(&en_flow_output, &en_sb_chassis, NULL); engine_add_input(&en_flow_output, &en_sb_encap, NULL); engine_add_input(&en_flow_output, &en_sb_address_set, NULL); @@ -913,6 +923,15 @@ main(int argc, char *argv[]) engine_add_input(&en_flow_output, &en_sb_dns, NULL); engine_add_input(&en_flow_output, &en_sb_gateway_chassis, NULL); + engine_add_input(&en_runtime_data, &en_ovs_port, NULL); + engine_add_input(&en_runtime_data, &en_ovs_interface, NULL); + + engine_add_input(&en_runtime_data, &en_sb_chassis, NULL); + engine_add_input(&en_runtime_data, &en_sb_address_set, NULL); + engine_add_input(&en_runtime_data, &en_sb_datapath_binding, NULL); + engine_add_input(&en_runtime_data, &en_sb_port_binding, NULL); + engine_add_input(&en_runtime_data, &en_sb_gateway_chassis, NULL); + engine_init(&en_flow_output); ofctrl_init(&ed_flow_output.group_table, @@ -925,9 +944,11 @@ main(int argc, char *argv[]) &pending_pkt); uint64_t engine_run_id = 0; + uint64_t old_engine_run_id = 0; /* Main loop. */ exiting = false; while (!exiting) { + old_engine_run_id = engine_run_id; /* Check OVN SB database. */ char *new_ovnsb_remote = get_ovnsb_remote(ovs_idl_loop.idl); if (strcmp(ovnsb_remote, new_ovnsb_remote)) { @@ -973,10 +994,13 @@ main(int argc, char *argv[]) &ed_runtime_data.local_datapaths, &ed_runtime_data.chassis_index); } - ofctrl_put(&ed_flow_output.flow_table, - &ed_runtime_data.pending_ct_zones, - get_nb_cfg(ctx.ovnsb_idl)); + if (en_flow_output.changed) { + ofctrl_put(&ed_flow_output.flow_table, + &ed_runtime_data.pending_ct_zones, + get_nb_cfg(ctx.ovnsb_idl)); + } } + pinctrl_run(&ctx, br_int, chassis, &ed_runtime_data.chassis_index, &ed_runtime_data.local_datapaths, &ed_runtime_data.active_tunnels); @@ -986,6 +1010,14 @@ main(int argc, char *argv[]) &ed_runtime_data.local_datapaths); } + if (old_engine_run_id == engine_run_id) { + VLOG_DBG("engine did not run, force recompute next time: " + "br_int %p, chassis %p", br_int, chassis); + engine_set_force_recompute(true); + poll_immediate_wake(); + } else { + engine_set_force_recompute(false); + } if (ctx.ovnsb_idl_txn) { int64_t cur_cfg = ofctrl_get_cur_cfg(); From patchwork Fri Jun 1 17:41:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 924266 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=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="FrNmB+vB"; dkim-atps=neutral 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 40yBcD3lv3z9s1w for ; Sat, 2 Jun 2018 03:47:24 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id F0D52F2F; Fri, 1 Jun 2018 17:42:53 +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 5FFF6EF9 for ; Fri, 1 Jun 2018 17:42:49 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f66.google.com (mail-pl0-f66.google.com [209.85.160.66]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 460D9708 for ; Fri, 1 Jun 2018 17:42:45 +0000 (UTC) Received: by mail-pl0-f66.google.com with SMTP id az12-v6so15720550plb.8 for ; Fri, 01 Jun 2018 10:42:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Tx62GNgzZpABpKoXHQJR4jwwatVyWUHE7mLIMpK9dc8=; b=FrNmB+vBJ3hopt4Lb4pUehsFiJUqPJabT4NZ2aEQawgbdx51SpVyF+zC6y7/Cykr6i Feb9T99g4OXBKceFea+HoQtiEszs5m6AcKs58Kx2oo/ljLtnj3NBBVl7QHLPaaPHwZzv mZD/igie4ircXCFTNJVrYBjbRKx8f6LtrFy0Yv/kqvzK7TRWJHcjDtwFnd1W8baYyjsQ y5wF0o1MjM04MAK6+XmGGH4Ox0lIm04HT1O8Lr18xKsDS1MI90vGovDusshyRhtZRM1m 5nD9EkwBQmqQlb0g7/5FJ15PLpcG6160zWIXUVPNQxlzzRohcrS0jOVLi3opAoc9WgJv IhNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Tx62GNgzZpABpKoXHQJR4jwwatVyWUHE7mLIMpK9dc8=; b=NNR3W5+IBr58rX8IyyFDS7qGRZlrrJ+yLZq7NuHrK4qh83q1hrlFzMti4gwd6OiOFb VWXGooWpaFz6/RCceyHvNPtOa2PCAcxc7etBYdrxV9r/eXEBj1/hlxTP5OMk+LM4OJsH Nq7F5IDHsMDQUfLIIPQ6/I6hTDFDPvpid6PggITLQlwvXL0kl9n2N92CzibxqNcHc7Hh XE3YbNgkndW08gIRhE6D5F9+2CiZvzevxxhryBS0aYvOV3tg4/+0sCKNsywIqh1IPnu4 taiOp86IYqN89u+AUBprgzcUvzzZJUZyusdA7Naxjh8W5Q+dP3wobRYi09xQaAKOpcjr EwAQ== X-Gm-Message-State: ALKqPwfUuFd9pk2+KWp01/tkQnAnHwQReSFORsfDZdekpacRe8bz2hQD WxbuQywYzwugqWIXLP4s5bSFTw== X-Google-Smtp-Source: ADUXVKJ392trIWoyaXlRyXxNSZoSLHeaj9fMahh1yDQ0Lu/XLPvyzln8qUCoTSEts2UNGiAhCVi1Yg== X-Received: by 2002:a17:902:369:: with SMTP id 96-v6mr12155494pld.64.1527874963822; Fri, 01 Jun 2018 10:42:43 -0700 (PDT) Received: from localhost.localdomain.localdomain (c-73-162-150-77.hsd1.ca.comcast.net. [73.162.150.77]) by smtp.gmail.com with ESMTPSA id v26-v6sm9600279pfe.13.2018.06.01.10.42.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 Jun 2018 10:42:43 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Fri, 1 Jun 2018 10:41:56 -0700 Message-Id: <1527874926-40450-7-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> References: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v3 06/16] ovn-controller: Incremental logical flow processing 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 Persistents flow-table and implements change handler of flow_output for SB lflow changes. Signed-off-by: Han Zhou --- include/ovn/actions.h | 3 + ovn/controller/lflow.c | 178 +++++++++++++++++++++++------ ovn/controller/lflow.h | 20 +++- ovn/controller/ofctrl.c | 241 ++++++++++++++++++++++++++++------------ ovn/controller/ofctrl.h | 27 ++++- ovn/controller/ovn-controller.c | 116 +++++++++++++------ ovn/controller/physical.c | 89 ++++++++------- ovn/controller/physical.h | 5 +- ovn/lib/actions.c | 6 +- ovn/lib/extend-table.c | 60 +++++++--- ovn/lib/extend-table.h | 16 ++- 11 files changed, 551 insertions(+), 210 deletions(-) diff --git a/include/ovn/actions.h b/include/ovn/actions.h index 6384651..5e4bd5b 100644 --- a/include/ovn/actions.h +++ b/include/ovn/actions.h @@ -520,6 +520,9 @@ struct ovnact_encode_params { /* A struct to figure out the meter_id for meter actions. */ struct ovn_extend_table *meter_table; + /* The logical flow uuid that drove this action. */ + struct uuid lflow_uuid; + /* OVN maps each logical flow table (ltable), one-to-one, onto a physical * OpenFlow flow table (ptable). A number of parameters describe this * mapping and data related to flow tables: diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c index d09fd10..9d8f693 100644 --- a/ovn/controller/lflow.c +++ b/ovn/controller/lflow.c @@ -61,7 +61,8 @@ struct condition_aux { const struct chassis_index *chassis_index; }; -static void consider_logical_flow(struct controller_ctx *ctx, +static bool consider_logical_flow(struct ovn_desired_flow_table *flow_table, + struct controller_ctx *ctx, const struct chassis_index *chassis_index, const struct sbrec_logical_flow *lflow, const struct hmap *local_datapaths, @@ -74,7 +75,6 @@ static void consider_logical_flow(struct controller_ctx *ctx, uint32_t *conj_id_ofs, const struct shash *addr_sets, const struct shash *port_groups, - struct hmap *flow_table, struct sset *active_tunnels, struct sset *local_lport_ids); @@ -137,7 +137,8 @@ is_switch(const struct sbrec_datapath_binding *ldp) /* Adds the logical flows from the Logical_Flow table to flow tables. */ static void -add_logical_flows(struct controller_ctx *ctx, +add_logical_flows(struct ovn_desired_flow_table *flow_table, + struct controller_ctx *ctx, const struct chassis_index *chassis_index, const struct hmap *local_datapaths, struct ovn_extend_table *group_table, @@ -145,11 +146,10 @@ add_logical_flows(struct controller_ctx *ctx, const struct sbrec_chassis *chassis, const struct shash *addr_sets, const struct shash *port_groups, - struct hmap *flow_table, struct sset *active_tunnels, - struct sset *local_lport_ids) + struct sset *local_lport_ids, + uint32_t *conj_id_ofs) { - uint32_t conj_id_ofs = 1; const struct sbrec_logical_flow *lflow; struct hmap dhcp_opts = HMAP_INITIALIZER(&dhcp_opts); @@ -171,12 +171,16 @@ add_logical_flows(struct controller_ctx *ctx, nd_ra_opts_init(&nd_ra_opts); SBREC_LOGICAL_FLOW_FOR_EACH (lflow, ctx->ovnsb_idl) { - consider_logical_flow(ctx, chassis_index, - lflow, local_datapaths, - group_table, meter_table, chassis, - &dhcp_opts, &dhcpv6_opts, &nd_ra_opts, - &conj_id_ofs, addr_sets, port_groups, - flow_table, active_tunnels, local_lport_ids); + if (!consider_logical_flow(flow_table, ctx, chassis_index, + lflow, local_datapaths, + group_table, meter_table, chassis, + &dhcp_opts, &dhcpv6_opts, &nd_ra_opts, + conj_id_ofs, addr_sets, port_groups, + active_tunnels, local_lport_ids)) { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5); + VLOG_ERR_RL(&rl, "Conjunction id overflow when processing lflow " + UUID_FMT, UUID_ARGS(&lflow->header_.uuid)); + } } dhcp_opts_destroy(&dhcp_opts); @@ -184,8 +188,95 @@ add_logical_flows(struct controller_ctx *ctx, nd_ra_opts_destroy(&nd_ra_opts); } -static void -consider_logical_flow(struct controller_ctx *ctx, +bool +lflow_handle_changed_flows(struct ovn_desired_flow_table *flow_table, + struct controller_ctx *ctx, + const struct sbrec_chassis *chassis, + const struct chassis_index *chassis_index, + const struct hmap *local_datapaths, + struct ovn_extend_table *group_table, + struct ovn_extend_table *meter_table, + const struct shash *addr_sets, + const struct shash *port_groups, + struct sset *active_tunnels, + struct sset *local_lport_ids, + uint32_t *conj_id_ofs) +{ + bool ret = true; + const struct sbrec_logical_flow *lflow; + + struct hmap dhcp_opts = HMAP_INITIALIZER(&dhcp_opts); + struct hmap dhcpv6_opts = HMAP_INITIALIZER(&dhcpv6_opts); + const struct sbrec_dhcp_options *dhcp_opt_row; + SBREC_DHCP_OPTIONS_FOR_EACH (dhcp_opt_row, ctx->ovnsb_idl) { + dhcp_opt_add(&dhcp_opts, dhcp_opt_row->name, dhcp_opt_row->code, + dhcp_opt_row->type); + } + + + const struct sbrec_dhcpv6_options *dhcpv6_opt_row; + SBREC_DHCPV6_OPTIONS_FOR_EACH(dhcpv6_opt_row, ctx->ovnsb_idl) { + dhcp_opt_add(&dhcpv6_opts, dhcpv6_opt_row->name, dhcpv6_opt_row->code, + dhcpv6_opt_row->type); + } + + struct hmap nd_ra_opts = HMAP_INITIALIZER(&nd_ra_opts); + nd_ra_opts_init(&nd_ra_opts); + + /* Handle removed flows first, and then other flows, so that when + * the flows being added and removed have same match conditions + * can be processed in the proper order */ + SBREC_LOGICAL_FLOW_FOR_EACH_TRACKED (lflow, ctx->ovnsb_idl) { + /* Remove any flows that should be removed. */ + if (sbrec_logical_flow_is_deleted(lflow)) { + VLOG_DBG("handle deleted lflow "UUID_FMT, + UUID_ARGS(&lflow->header_.uuid)); + ofctrl_remove_flows(flow_table, &lflow->header_.uuid); + } + } + SBREC_LOGICAL_FLOW_FOR_EACH_TRACKED (lflow, ctx->ovnsb_idl) { + if (!sbrec_logical_flow_is_deleted(lflow)) { + /* Now, add/modify existing flows. If the logical + * flow is a modification, just remove the flows + * for this row, and then add new flows. */ + if (!sbrec_logical_flow_is_new(lflow)) { + VLOG_DBG("handle updated lflow "UUID_FMT, + UUID_ARGS(&lflow->header_.uuid)); + ofctrl_remove_flows(flow_table, &lflow->header_.uuid); + } + VLOG_DBG("handle new lflow "UUID_FMT, + UUID_ARGS(&lflow->header_.uuid)); + if (!consider_logical_flow(flow_table, ctx, chassis_index, + lflow, local_datapaths, + group_table, meter_table, chassis, + &dhcp_opts, &dhcpv6_opts, &nd_ra_opts, + conj_id_ofs, addr_sets, port_groups, + active_tunnels, local_lport_ids)) { + ret = false; + break; + } + } + } + dhcp_opts_destroy(&dhcp_opts); + dhcp_opts_destroy(&dhcpv6_opts); + nd_ra_opts_destroy(&nd_ra_opts); + return ret; +} + +static bool +update_conj_id_ofs(uint32_t *conj_id_ofs, uint32_t n_conjs) +{ + if (*conj_id_ofs + n_conjs < *conj_id_ofs) { + /* overflow */ + return false; + } + *conj_id_ofs += n_conjs; + return true; +} + +static bool +consider_logical_flow(struct ovn_desired_flow_table *flow_table, + struct controller_ctx *ctx, const struct chassis_index *chassis_index, const struct sbrec_logical_flow *lflow, const struct hmap *local_datapaths, @@ -198,7 +289,6 @@ consider_logical_flow(struct controller_ctx *ctx, uint32_t *conj_id_ofs, const struct shash *addr_sets, const struct shash *port_groups, - struct hmap *flow_table, struct sset *active_tunnels, struct sset *local_lport_ids) { @@ -207,10 +297,14 @@ consider_logical_flow(struct controller_ctx *ctx, const struct sbrec_datapath_binding *ldp = lflow->logical_datapath; if (!ldp) { - return; + VLOG_DBG("lflow "UUID_FMT" has no datapath binding, skip", + UUID_ARGS(&lflow->header_.uuid)); + return true; } if (!get_local_datapath(local_datapaths, ldp->tunnel_key)) { - return; + VLOG_DBG("lflow "UUID_FMT" is not for local datapath, skip", + UUID_ARGS(&lflow->header_.uuid)); + return true; } /* Determine translation of logical table IDs to physical table IDs. */ @@ -248,7 +342,7 @@ consider_logical_flow(struct controller_ctx *ctx, free(error); ovnacts_free(ovnacts.data, ovnacts.size); ofpbuf_uninit(&ovnacts); - return; + return true; } /* Translate OVN match into table of OpenFlow matches. */ @@ -272,7 +366,7 @@ consider_logical_flow(struct controller_ctx *ctx, free(error); ovnacts_free(ovnacts.data, ovnacts.size); ofpbuf_uninit(&ovnacts); - return; + return true; } struct lookup_port_aux aux = { @@ -288,10 +382,12 @@ consider_logical_flow(struct controller_ctx *ctx, expr_destroy(expr); if (hmap_is_empty(&matches)) { + VLOG_DBG("lflow "UUID_FMT" matches are empty, skip", + UUID_ARGS(&lflow->header_.uuid)); ovnacts_free(ovnacts.data, ovnacts.size); ofpbuf_uninit(&ovnacts); expr_matches_destroy(&matches); - return; + return true; } /* Encode OVN logical actions into OpenFlow. */ @@ -303,6 +399,7 @@ consider_logical_flow(struct controller_ctx *ctx, .is_switch = is_switch(ldp), .group_table = group_table, .meter_table = meter_table, + .lflow_uuid = lflow->header_.uuid, .pipeline = ingress ? OVNACT_P_INGRESS : OVNACT_P_EGRESS, .ingress_ptable = OFTABLE_LOG_INGRESS_PIPELINE, @@ -331,13 +428,18 @@ consider_logical_flow(struct controller_ctx *ctx, char buf[16]; snprintf(buf, sizeof(buf), "%"PRId64"_%"PRId64, dp_id, port_id); if (!sset_contains(local_lport_ids, buf)) { + VLOG_DBG("lflow "UUID_FMT + " port %s in match is not local, skip", + UUID_ARGS(&lflow->header_.uuid), + buf); continue; } } } if (!m->n) { ofctrl_add_flow(flow_table, ptable, lflow->priority, - lflow->header_.uuid.parts[0], &m->match, &ofpacts); + lflow->header_.uuid.parts[0], &m->match, &ofpacts, + &lflow->header_.uuid); } else { uint64_t conj_stubs[64 / 8]; struct ofpbuf conj; @@ -353,7 +455,7 @@ consider_logical_flow(struct controller_ctx *ctx, dst->n_clauses = src->n_clauses; } ofctrl_add_flow(flow_table, ptable, lflow->priority, 0, &m->match, - &conj); + &conj, &lflow->header_.uuid); ofpbuf_uninit(&conj); } } @@ -361,7 +463,7 @@ consider_logical_flow(struct controller_ctx *ctx, /* Clean up. */ expr_matches_destroy(&matches); ofpbuf_uninit(&ofpacts); - *conj_id_ofs += n_conjs; + return update_conj_id_ofs(conj_id_ofs, n_conjs); } static void @@ -377,9 +479,9 @@ put_load(const uint8_t *data, size_t len, } static void -consider_neighbor_flow(struct controller_ctx *ctx, - const struct sbrec_mac_binding *b, - struct hmap *flow_table) +consider_neighbor_flow(struct ovn_desired_flow_table *flow_table, + struct controller_ctx *ctx, + const struct sbrec_mac_binding *b) { const struct sbrec_port_binding *pb = lport_lookup_by_name(ctx->ovnsb_idl, b->logical_port); @@ -421,26 +523,28 @@ consider_neighbor_flow(struct controller_ctx *ctx, uint64_t stub[1024 / 8]; struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(stub); put_load(mac.ea, sizeof mac.ea, MFF_ETH_DST, 0, 48, &ofpacts); - ofctrl_add_flow(flow_table, OFTABLE_MAC_BINDING, 100, 0, &match, &ofpacts); + ofctrl_add_flow(flow_table, OFTABLE_MAC_BINDING, 100, 0, &match, &ofpacts, + &b->header_.uuid); ofpbuf_uninit(&ofpacts); } /* Adds an OpenFlow flow to flow tables for each MAC binding in the OVN * southbound database. */ static void -add_neighbor_flows(struct controller_ctx *ctx, - struct hmap *flow_table) +add_neighbor_flows(struct ovn_desired_flow_table *flow_table, + struct controller_ctx *ctx) { const struct sbrec_mac_binding *b; SBREC_MAC_BINDING_FOR_EACH (b, ctx->ovnsb_idl) { - consider_neighbor_flow(ctx, b, flow_table); + consider_neighbor_flow(flow_table, ctx, b); } } /* Translates logical flows in the Logical_Flow table in the OVN_SB database * into OpenFlow flows. See ovn-architecture(7) for more information. */ void -lflow_run(struct controller_ctx *ctx, +lflow_run(struct ovn_desired_flow_table *flow_table, + struct controller_ctx *ctx, const struct sbrec_chassis *chassis, const struct chassis_index *chassis_index, const struct hmap *local_datapaths, @@ -448,17 +552,17 @@ lflow_run(struct controller_ctx *ctx, struct ovn_extend_table *meter_table, const struct shash *addr_sets, const struct shash *port_groups, - struct hmap *flow_table, struct sset *active_tunnels, - struct sset *local_lport_ids) + struct sset *local_lport_ids, + uint32_t *conj_id_ofs) { COVERAGE_INC(lflow_run); - add_logical_flows(ctx, chassis_index, local_datapaths, + add_logical_flows(flow_table, ctx, chassis_index, local_datapaths, group_table, meter_table, chassis, addr_sets, - port_groups, flow_table, active_tunnels, - local_lport_ids); - add_neighbor_flows(ctx, flow_table); + port_groups, active_tunnels, local_lport_ids, + conj_id_ofs); + add_neighbor_flows(flow_table, ctx); } void diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h index dcf2fe7..d407c2c 100644 --- a/ovn/controller/lflow.h +++ b/ovn/controller/lflow.h @@ -38,6 +38,7 @@ struct chassis_index; struct controller_ctx; struct ovn_extend_table; +struct ovn_desired_flow_table; struct hmap; struct sbrec_chassis; struct simap; @@ -62,7 +63,8 @@ struct uuid; #define LOG_PIPELINE_LEN 24 void lflow_init(void); -void lflow_run(struct controller_ctx *, +void lflow_run(struct ovn_desired_flow_table *, + struct controller_ctx *, const struct sbrec_chassis *chassis, const struct chassis_index *, const struct hmap *local_datapaths, @@ -70,9 +72,21 @@ void lflow_run(struct controller_ctx *, struct ovn_extend_table *meter_table, const struct shash *addr_sets, const struct shash *port_groups, - struct hmap *flow_table, struct sset *active_tunnels, - struct sset *local_lport_ids); + struct sset *local_lport_ids, + uint32_t *conj_id_ofs); +bool lflow_handle_changed_flows(struct ovn_desired_flow_table *, + struct controller_ctx *ctx, + const struct sbrec_chassis *chassis, + const struct chassis_index *chassis_index, + const struct hmap *local_datapaths, + struct ovn_extend_table *group_table, + struct ovn_extend_table *extend_table, + const struct shash *addr_sets, + const struct shash *port_groups, + struct sset *active_tunnels, + struct sset *local_lport_ids, + uint32_t *conj_id_ofs); void lflow_destroy(void); #endif /* ovn/lflow.h */ diff --git a/ovn/controller/ofctrl.c b/ovn/controller/ofctrl.c index 134f0e5..dda486d 100644 --- a/ovn/controller/ofctrl.c +++ b/ovn/controller/ofctrl.c @@ -20,6 +20,7 @@ #include "dp-packet.h" #include "flow.h" #include "hash.h" +#include "hindex.h" #include "lflow.h" #include "ofctrl.h" #include "openflow/openflow.h" @@ -52,7 +53,8 @@ VLOG_DEFINE_THIS_MODULE(ofctrl); /* An OpenFlow flow. */ struct ovn_flow { - struct hmap_node hmap_node; /* For match based hashing. */ + struct hmap_node match_hmap_node; /* For match based hashing. */ + struct hindex_node uuid_hindex_node; /* For uuid based hashing. */ struct ovs_list list_node; /* For handling lists of flows. */ /* Key. */ @@ -61,14 +63,16 @@ struct ovn_flow { struct minimatch match; /* Data. */ + struct uuid sb_uuid; struct ofpact *ofpacts; size_t ofpacts_len; uint64_t cookie; }; -static uint32_t ovn_flow_hash(const struct ovn_flow *); +static uint32_t ovn_flow_match_hash(const struct ovn_flow *); static struct ovn_flow *ovn_flow_lookup(struct hmap *flow_table, - const struct ovn_flow *target); + const struct ovn_flow *target, + bool cmp_sb_uuid); static char *ovn_flow_to_string(const struct ovn_flow *); static void ovn_flow_log(const struct ovn_flow *, const char *action); static void ovn_flow_destroy(struct ovn_flow *); @@ -146,6 +150,10 @@ static struct ovn_extend_table *meters; * S_CLEAR_FLOWS or S_UPDATE_FLOWS, this is really the option we have. */ static enum mf_field_id mff_ovn_geneve; +/* Indicates if flows need to be reinstalled for scenarios when ovs + * is restarted, even if there is no change in the desired flow table. */ +static bool need_reinstall_flows; + static ovs_be32 queue_msg(struct ofpbuf *); static struct ofpbuf *encode_flow_mod(struct ofputil_flow_mod *); @@ -154,8 +162,8 @@ static struct ofpbuf *encode_group_mod(const struct ofputil_group_mod *); static struct ofpbuf *encode_meter_mod(const struct ofputil_meter_mod *); -static void ovn_flow_table_clear(struct hmap *flow_table); -static void ovn_flow_table_destroy(struct hmap *flow_table); +static void ovn_installed_flow_table_clear(void); +static void ovn_installed_flow_table_destroy(void); static void ofctrl_recv(const struct ofp_header *, enum ofptype); @@ -375,6 +383,7 @@ run_S_CLEAR_FLOWS(void) { VLOG_DBG("clearing all flows"); + need_reinstall_flows = true; /* Send a flow_mod to delete all flows. */ struct ofputil_flow_mod fm = { .table_id = OFPTT_ALL, @@ -384,9 +393,6 @@ run_S_CLEAR_FLOWS(void) queue_msg(encode_flow_mod(&fm)); minimatch_destroy(&fm.match); - /* Clear installed_flows, to match the state of the switch. */ - ovn_flow_table_clear(&installed_flows); - /* Send a group_mod to delete all groups. */ struct ofputil_group_mod gm; memset(&gm, 0, sizeof gm); @@ -397,6 +403,9 @@ run_S_CLEAR_FLOWS(void) queue_msg(encode_group_mod(&gm)); ofputil_uninit_group_mod(&gm); + /* Clear installed_flows, to match the state of the switch. */ + ovn_installed_flow_table_clear(); + /* Clear existing groups, to match the state of the switch. */ if (groups) { ovn_extend_table_clear(groups, true); @@ -580,7 +589,7 @@ void ofctrl_destroy(void) { rconn_destroy(swconn); - ovn_flow_table_destroy(&installed_flows); + ovn_installed_flow_table_destroy(); rconn_packet_counter_destroy(tx_counter); expr_symtab_destroy(&symtab); shash_destroy(&symtab); @@ -632,14 +641,17 @@ ofctrl_recv(const struct ofp_header *oh, enum ofptype type) * the OpenFlow table numbered 'table_id' with the given 'priority' and * OpenFlow 'cookie'. The caller retains ownership of 'match' and 'actions'. * + * The flow is also added to a hash index based on sb_uuid. + * * This just assembles the desired flow table in memory. Nothing is actually * sent to the switch until a later call to ofctrl_put(). * * The caller should initialize its own hmap to hold the flows. */ void -ofctrl_add_flow(struct hmap *desired_flows, +ofctrl_add_flow(struct ovn_desired_flow_table *flow_table, uint8_t table_id, uint16_t priority, uint64_t cookie, - const struct match *match, const struct ofpbuf *actions) + const struct match *match, const struct ofpbuf *actions, + const struct uuid *sb_uuid) { struct ovn_flow *f = xmalloc(sizeof *f); f->table_id = table_id; @@ -647,10 +659,14 @@ ofctrl_add_flow(struct hmap *desired_flows, minimatch_init(&f->match, match); f->ofpacts = xmemdup(actions->data, actions->size); f->ofpacts_len = actions->size; - f->hmap_node.hash = ovn_flow_hash(f); + f->sb_uuid = *sb_uuid; + f->match_hmap_node.hash = ovn_flow_match_hash(f); + f->uuid_hindex_node.hash = uuid_hash(&f->sb_uuid); f->cookie = cookie; - if (ovn_flow_lookup(desired_flows, f)) { + ovn_flow_log(f, "ofctrl_add_flow"); + + if (ovn_flow_lookup(&flow_table->match_flow_table, f, true)) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5); if (!VLOG_DROP_DBG(&rl)) { char *s = ovn_flow_to_string(f); @@ -662,19 +678,44 @@ ofctrl_add_flow(struct hmap *desired_flows, return; } - hmap_insert(desired_flows, &f->hmap_node, f->hmap_node.hash); + hmap_insert(&flow_table->match_flow_table, &f->match_hmap_node, + f->match_hmap_node.hash); + hindex_insert(&flow_table->uuid_flow_table, &f->uuid_hindex_node, + f->uuid_hindex_node.hash); +} + +/* Removes a bundles of flows from the flow table. */ +void +ofctrl_remove_flows(struct ovn_desired_flow_table *flow_table, + const struct uuid *sb_uuid) +{ + struct ovn_flow *f, *next; + HINDEX_FOR_EACH_WITH_HASH_SAFE (f, next, uuid_hindex_node, + uuid_hash(sb_uuid), + &flow_table->uuid_flow_table) { + if (uuid_equals(&f->sb_uuid, sb_uuid)) { + ovn_flow_log(f, "ofctrl_remove_flow"); + hmap_remove(&flow_table->match_flow_table, + &f->match_hmap_node); + hindex_remove(&flow_table->uuid_flow_table, &f->uuid_hindex_node); + ovn_flow_destroy(f); + } + } + + /* remove any related group and meter info */ + ovn_extend_table_remove_desired(groups, sb_uuid); + ovn_extend_table_remove_desired(meters, sb_uuid); } /* ovn_flow. */ -/* Returns a hash of the key in 'f'. */ +/* Returns a hash of the match key in 'f'. */ static uint32_t -ovn_flow_hash(const struct ovn_flow *f) +ovn_flow_match_hash(const struct ovn_flow *f) { return hash_2words((f->table_id << 16) | f->priority, minimatch_hash(&f->match, 0)); - } /* Duplicate an ovn_flow structure. */ @@ -687,23 +728,28 @@ ofctrl_dup_flow(struct ovn_flow *src) minimatch_clone(&dst->match, &src->match); dst->ofpacts = xmemdup(src->ofpacts, src->ofpacts_len); dst->ofpacts_len = src->ofpacts_len; - dst->hmap_node.hash = ovn_flow_hash(dst); + dst->sb_uuid = src->sb_uuid; + dst->match_hmap_node.hash = ovn_flow_match_hash(dst); + dst->uuid_hindex_node.hash = uuid_hash(&src->sb_uuid); return dst; } /* Finds and returns an ovn_flow in 'flow_table' whose key is identical to * 'target''s key, or NULL if there is none. */ static struct ovn_flow * -ovn_flow_lookup(struct hmap *flow_table, const struct ovn_flow *target) +ovn_flow_lookup(struct hmap *flow_table, const struct ovn_flow *target, + bool cmp_sb_uuid) { struct ovn_flow *f; - HMAP_FOR_EACH_WITH_HASH (f, hmap_node, target->hmap_node.hash, + HMAP_FOR_EACH_WITH_HASH (f, match_hmap_node, target->match_hmap_node.hash, flow_table) { if (f->table_id == target->table_id && f->priority == target->priority && minimatch_equal(&f->match, &target->match)) { - return f; + if (!cmp_sb_uuid || uuid_equals(&target->sb_uuid, &f->sb_uuid)) { + return f; + } } } return NULL; @@ -713,6 +759,7 @@ static char * ovn_flow_to_string(const struct ovn_flow *f) { struct ds s = DS_EMPTY_INITIALIZER; + ds_put_format(&s, "sb_uuid="UUID_FMT", ", UUID_ARGS(&f->sb_uuid)); ds_put_format(&s, "table_id=%"PRIu8", ", f->table_id); ds_put_format(&s, "priority=%"PRIu16", ", f->priority); minimatch_format(&f->match, NULL, NULL, &s, OFP_DEFAULT_PRIORITY); @@ -743,22 +790,48 @@ ovn_flow_destroy(struct ovn_flow *f) } /* Flow tables of struct ovn_flow. */ +void +ovn_desired_flow_table_init(struct ovn_desired_flow_table *flow_table) +{ + hmap_init(&flow_table->match_flow_table); + hindex_init(&flow_table->uuid_flow_table); +} + +void +ovn_desired_flow_table_clear(struct ovn_desired_flow_table *flow_table) +{ + struct ovn_flow *f, *next; + HMAP_FOR_EACH_SAFE (f, next, match_hmap_node, + &flow_table->match_flow_table) { + hmap_remove(&flow_table->match_flow_table, &f->match_hmap_node); + hindex_remove(&flow_table->uuid_flow_table, &f->uuid_hindex_node); + ovn_flow_destroy(f); + } +} + +void +ovn_desired_flow_table_destroy(struct ovn_desired_flow_table *flow_table) +{ + ovn_desired_flow_table_clear(flow_table); + hmap_destroy(&flow_table->match_flow_table); + hindex_destroy(&flow_table->uuid_flow_table); +} static void -ovn_flow_table_clear(struct hmap *flow_table) +ovn_installed_flow_table_clear(void) { struct ovn_flow *f, *next; - HMAP_FOR_EACH_SAFE (f, next, hmap_node, flow_table) { - hmap_remove(flow_table, &f->hmap_node); + HMAP_FOR_EACH_SAFE (f, next, match_hmap_node, &installed_flows) { + hmap_remove(&installed_flows, &f->match_hmap_node); ovn_flow_destroy(f); } } static void -ovn_flow_table_destroy(struct hmap *flow_table) +ovn_installed_flow_table_destroy(void) { - ovn_flow_table_clear(flow_table); - hmap_destroy(flow_table); + ovn_installed_flow_table_clear(); + hmap_destroy(&installed_flows); } /* Flow table update. */ @@ -823,7 +896,7 @@ add_ct_flush_zone(uint16_t zone_id, struct ovs_list *msgs) * in the correct state and not backlogged with existing flow_mods. (Our * criteria for being backlogged appear very conservative, but the socket * between ovn-controller and OVS provides some buffering.) */ -bool +static bool ofctrl_can_put(void) { if (state != S_UPDATE_FLOWS @@ -838,9 +911,7 @@ ofctrl_can_put(void) * with ofctrl_add_flow(). * * Replaces the group table and meter table on the switch, if possible, by the - * contents of 'groups->desired'. Regardless of whether the group table - * is updated, this deletes all the groups from the 'groups->desired' and frees - * them. (The hmap itself isn't destroyed.) + * contents of 'desired'. * * Sends conntrack flush messages to each zone in 'pending_ct_zones' that * is in the CT_ZONE_OF_QUEUED state and then moves the zone into the @@ -848,16 +919,42 @@ ofctrl_can_put(void) * * This should be called after ofctrl_run() within the main loop. */ void -ofctrl_put(struct hmap *flow_table, struct shash *pending_ct_zones, - int64_t nb_cfg) +ofctrl_put(struct ovn_desired_flow_table *flow_table, + struct shash *pending_ct_zones, + int64_t nb_cfg, + bool flow_changed) { + static bool skipped_last_time = false; + static int64_t old_nb_cfg = 0; + bool need_put = false; + if (flow_changed || skipped_last_time || need_reinstall_flows) { + need_put = true; + } else if (nb_cfg != old_nb_cfg) { + /* nb_cfg changed since last ofctrl_put() call */ + if (cur_cfg == old_nb_cfg) { + /* we were up-to-date already, so just update with the + * new nb_cfg */ + cur_cfg = nb_cfg; + } else { + need_put = true; + } + } + + old_nb_cfg = nb_cfg; + + if (!need_put) { + VLOG_DBG("ofctrl_put not needed"); + return; + } if (!ofctrl_can_put()) { - ovn_flow_table_clear(flow_table); - ovn_extend_table_clear(groups, false); - ovn_extend_table_clear(meters, false); + VLOG_DBG("ofctrl_put can't be performed"); + skipped_last_time = true; return; } + skipped_last_time = false; + need_reinstall_flows = false; + /* OpenFlow messages to send to the switch to bring it up-to-date. */ struct ovs_list msgs = OVS_LIST_INITIALIZER(&msgs); @@ -921,8 +1018,9 @@ ofctrl_put(struct hmap *flow_table, struct shash *pending_ct_zones, * longer desired, delete them; if any of them should have different * actions, update them. */ struct ovn_flow *i, *next; - HMAP_FOR_EACH_SAFE (i, next, hmap_node, &installed_flows) { - struct ovn_flow *d = ovn_flow_lookup(flow_table, i); + HMAP_FOR_EACH_SAFE (i, next, match_hmap_node, &installed_flows) { + struct ovn_flow *d = ovn_flow_lookup(&flow_table->match_flow_table, + i, false); if (!d) { /* Installed flow is no longer desirable. Delete it from the * switch and from installed_flows. */ @@ -935,9 +1033,13 @@ ofctrl_put(struct hmap *flow_table, struct shash *pending_ct_zones, add_flow_mod(&fm, &msgs); ovn_flow_log(i, "removing installed"); - hmap_remove(&installed_flows, &i->hmap_node); + hmap_remove(&installed_flows, &i->match_hmap_node); ovn_flow_destroy(i); } else { + if (!uuid_equals(&i->sb_uuid, &d->sb_uuid)) { + /* Update installed flow's UUID. */ + i->sb_uuid = d->sb_uuid; + } if (!ofpacts_equal(i->ofpacts, i->ofpacts_len, d->ofpacts, d->ofpacts_len)) { /* Update actions in installed flow. */ @@ -954,38 +1056,37 @@ ofctrl_put(struct hmap *flow_table, struct shash *pending_ct_zones, /* Replace 'i''s actions by 'd''s. */ free(i->ofpacts); - i->ofpacts = d->ofpacts; + i->ofpacts = xmemdup(d->ofpacts, d->ofpacts_len); i->ofpacts_len = d->ofpacts_len; - d->ofpacts = NULL; - d->ofpacts_len = 0; } - hmap_remove(flow_table, &d->hmap_node); - ovn_flow_destroy(d); } } - /* The previous loop removed from 'flow_table' all of the flows that are - * already installed. Thus, any flows remaining in 'flow_table' need to - * be added to the flow table. */ + /* Iterate through the desired flows and add those that aren't found + * in the installed flow table. */ struct ovn_flow *d; - HMAP_FOR_EACH_SAFE (d, next, hmap_node, flow_table) { - /* Send flow_mod to add flow. */ - struct ofputil_flow_mod fm = { - .match = d->match, - .priority = d->priority, - .table_id = d->table_id, - .ofpacts = d->ofpacts, - .ofpacts_len = d->ofpacts_len, - .new_cookie = htonll(d->cookie), - .command = OFPFC_ADD, - }; - add_flow_mod(&fm, &msgs); - ovn_flow_log(d, "adding installed"); - - /* Move 'd' from 'flow_table' to installed_flows. */ - hmap_remove(flow_table, &d->hmap_node); - hmap_insert(&installed_flows, &d->hmap_node, d->hmap_node.hash); + HMAP_FOR_EACH (d, match_hmap_node, &flow_table->match_flow_table) { + i = ovn_flow_lookup(&installed_flows, d, false); + if (!i) { + /* Send flow_mod to add flow. */ + struct ofputil_flow_mod fm = { + .match = d->match, + .priority = d->priority, + .table_id = d->table_id, + .ofpacts = d->ofpacts, + .ofpacts_len = d->ofpacts_len, + .new_cookie = htonll(d->cookie), + .command = OFPFC_ADD, + }; + add_flow_mod(&fm, &msgs); + ovn_flow_log(d, "adding installed"); + + /* Copy 'd' from 'flow_table' to installed_flows. */ + struct ovn_flow *new_node = ofctrl_dup_flow(d); + hmap_insert(&installed_flows, &new_node->match_hmap_node, + new_node->match_hmap_node.hash); + } } /* Iterate through the installed groups from previous runs. If they @@ -1010,11 +1111,11 @@ ofctrl_put(struct hmap *flow_table, struct shash *pending_ct_zones, } free(group_string); ofputil_uninit_group_mod(&gm); - ovn_extend_table_remove(groups, installed); + ovn_extend_table_remove_existing(groups, installed); } - /* Move the contents of groups->desired to groups->existing. */ - ovn_extend_table_move(groups); + /* Sync the contents of groups->desired to groups->existing. */ + ovn_extend_table_sync(groups); /* Iterate through the installed meters from previous runs. If they * are not needed delete them. */ @@ -1037,11 +1138,11 @@ ofctrl_put(struct hmap *flow_table, struct shash *pending_ct_zones, free(error); } free(meter_string); - ovn_extend_table_remove(meters, m_installed); + ovn_extend_table_remove_existing(meters, m_installed); } - /* Move the contents of meters->desired to meters->existing. */ - ovn_extend_table_move(meters); + /* Sync the contents of meters->desired to meters->existing. */ + ovn_extend_table_sync(meters); if (!ovs_list_is_empty(&msgs)) { /* Add a barrier to the list of messages. */ diff --git a/ovn/controller/ofctrl.h b/ovn/controller/ofctrl.h index 45081e5..587eca5 100644 --- a/ovn/controller/ofctrl.h +++ b/ovn/controller/ofctrl.h @@ -21,6 +21,7 @@ #include "openvswitch/meta-flow.h" #include "ovsdb-idl.h" +#include "hindex.h" struct controller_ctx; struct ovn_extend_table; @@ -30,15 +31,24 @@ struct ofpbuf; struct ovsrec_bridge; struct shash; +struct ovn_desired_flow_table { + /* Hash map flow table using flow match conditions as hash key.*/ + struct hmap match_flow_table; + + /* SB uuid index for the nodes in match_flow_table.*/ + struct hindex uuid_flow_table; +}; + /* Interface for OVN main loop. */ void ofctrl_init(struct ovn_extend_table *group_table, struct ovn_extend_table *meter_table); void ofctrl_run(const struct ovsrec_bridge *br_int, struct shash *pending_ct_zones); enum mf_field_id ofctrl_get_mf_field_id(void); -bool ofctrl_can_put(void); -void ofctrl_put(struct hmap *flow_table, struct shash *pending_ct_zones, - int64_t nb_cfg); +void ofctrl_put(struct ovn_desired_flow_table *, + struct shash *pending_ct_zones, + int64_t nb_cfg, + bool flow_changed); void ofctrl_wait(void); void ofctrl_destroy(void); int64_t ofctrl_get_cur_cfg(void); @@ -52,8 +62,15 @@ char *ofctrl_inject_pkt(const struct ovsrec_bridge *br_int, const struct shash *port_groups); /* Flow table interfaces to the rest of ovn-controller. */ -void ofctrl_add_flow(struct hmap *desired_flows, uint8_t table_id, +void ofctrl_add_flow(struct ovn_desired_flow_table *, uint8_t table_id, uint16_t priority, uint64_t cookie, - const struct match *, const struct ofpbuf *ofpacts); + const struct match *, const struct ofpbuf *ofpacts, + const struct uuid *); + +void ofctrl_remove_flows(struct ovn_desired_flow_table *, const struct uuid *); + +void ovn_desired_flow_table_init(struct ovn_desired_flow_table *); +void ovn_desired_flow_table_clear(struct ovn_desired_flow_table *); +void ovn_desired_flow_table_destroy(struct ovn_desired_flow_table *); #endif /* ovn/ofctrl.h */ diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index e390afd..7f81c93 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -747,11 +747,13 @@ en_runtime_data_run(struct engine_node *node) struct ed_type_flow_output { /* desired flows */ - struct hmap flow_table; + struct ovn_desired_flow_table flow_table; /* group ids for load balancing */ struct ovn_extend_table group_table; /* meter ids for QoS */ struct ovn_extend_table meter_table; + /* conjunction id offset */ + uint32_t conj_id_ofs; }; static void @@ -759,9 +761,10 @@ en_flow_output_init(struct engine_node *node) { struct ed_type_flow_output *data = (struct ed_type_flow_output *)node->data; - hmap_init(&data->flow_table); + ovn_desired_flow_table_init(&data->flow_table); ovn_extend_table_init(&data->group_table); ovn_extend_table_init(&data->meter_table); + data->conj_id_ofs = 1; } static void @@ -769,7 +772,7 @@ en_flow_output_cleanup(struct engine_node *node) { struct ed_type_flow_output *data = (struct ed_type_flow_output *)node->data; - hmap_destroy(&data->flow_table); + ovn_desired_flow_table_destroy(&data->flow_table); ovn_extend_table_destroy(&data->group_table); ovn_extend_table_destroy(&data->meter_table); } @@ -803,29 +806,75 @@ en_flow_output_run(struct engine_node *node) struct ed_type_flow_output *fo = (struct ed_type_flow_output *)node->data; - struct hmap *flow_table = &fo->flow_table; + struct ovn_desired_flow_table *flow_table = &fo->flow_table; struct ovn_extend_table *group_table = &fo->group_table; struct ovn_extend_table *meter_table = &fo->meter_table; + uint32_t *conj_id_ofs = &fo->conj_id_ofs; static bool first_run = true; if (first_run) { first_run = false; } else { - hmap_clear(flow_table); + ovn_desired_flow_table_clear(flow_table); + ovn_extend_table_clear(group_table, false /* desired */); + ovn_extend_table_clear(meter_table, false /* desired */); } - lflow_run(ctx, chassis, + *conj_id_ofs = 1; + lflow_run(flow_table, ctx, chassis, chassis_index, local_datapaths, group_table, - meter_table, addr_sets, port_groups, flow_table, - active_tunnels, local_lport_ids); + meter_table, addr_sets, port_groups, active_tunnels, + local_lport_ids, conj_id_ofs); enum mf_field_id mff_ovn_geneve = ofctrl_get_mf_field_id(); - physical_run(ctx, mff_ovn_geneve, + physical_run(flow_table, ctx, mff_ovn_geneve, br_int, chassis, ct_zones, - flow_table, local_datapaths, local_lports, + local_datapaths, local_lports, chassis_index, active_tunnels); + + node->changed = true; +} + +static bool +flow_output_sb_logical_flow_handler(struct engine_node *node) +{ + struct controller_ctx *ctx = (struct controller_ctx *)node->context; + struct ed_type_runtime_data *data = + (struct ed_type_runtime_data *)engine_get_input( + "runtime_data", node)->data; + struct hmap *local_datapaths = &data->local_datapaths; + struct sset *local_lport_ids = &data->local_lport_ids; + struct sset *active_tunnels = &data->active_tunnels; + struct chassis_index *chassis_index = &data->chassis_index; + struct shash *addr_sets = &data->addr_sets; + struct shash *port_groups = &data->port_groups; + const struct ovsrec_bridge *br_int = get_br_int(ctx); + + const char *chassis_id = get_chassis_id(ctx->ovs_idl); + + + const struct sbrec_chassis *chassis = NULL; + if (chassis_id) { + chassis = get_chassis(ctx->ovnsb_idl, chassis_id); + } + + ovs_assert(br_int && chassis); + + struct ed_type_flow_output *fo = + (struct ed_type_flow_output *)node->data; + struct ovn_desired_flow_table *flow_table = &fo->flow_table; + struct ovn_extend_table *group_table = &fo->group_table; + struct ovn_extend_table *meter_table = &fo->meter_table; + uint32_t *conj_id_ofs = &fo->conj_id_ofs; + + bool handled = lflow_handle_changed_flows(flow_table, ctx, chassis, + chassis_index, local_datapaths, group_table, meter_table, + addr_sets, port_groups, active_tunnels, local_lport_ids, + conj_id_ofs); + node->changed = true; + return handled; } int @@ -911,13 +960,11 @@ main(int argc, char *argv[]) engine_add_input(&en_flow_output, &en_sb_chassis, NULL); engine_add_input(&en_flow_output, &en_sb_encap, NULL); - engine_add_input(&en_flow_output, &en_sb_address_set, NULL); - engine_add_input(&en_flow_output, &en_sb_port_group, NULL); engine_add_input(&en_flow_output, &en_sb_multicast_group, NULL); engine_add_input(&en_flow_output, &en_sb_datapath_binding, NULL); engine_add_input(&en_flow_output, &en_sb_port_binding, NULL); engine_add_input(&en_flow_output, &en_sb_mac_binding, NULL); - engine_add_input(&en_flow_output, &en_sb_logical_flow, NULL); + engine_add_input(&en_flow_output, &en_sb_logical_flow, flow_output_sb_logical_flow_handler); engine_add_input(&en_flow_output, &en_sb_dhcp_options, NULL); engine_add_input(&en_flow_output, &en_sb_dhcpv6_options, NULL); engine_add_input(&en_flow_output, &en_sb_dns, NULL); @@ -928,6 +975,7 @@ main(int argc, char *argv[]) engine_add_input(&en_runtime_data, &en_sb_chassis, NULL); engine_add_input(&en_runtime_data, &en_sb_address_set, NULL); + engine_add_input(&en_runtime_data, &en_sb_port_group, NULL); engine_add_input(&en_runtime_data, &en_sb_datapath_binding, NULL); engine_add_input(&en_runtime_data, &en_sb_port_binding, NULL); engine_add_input(&en_runtime_data, &en_sb_gateway_chassis, NULL); @@ -945,6 +993,7 @@ main(int argc, char *argv[]) uint64_t engine_run_id = 0; uint64_t old_engine_run_id = 0; + /* Main loop. */ exiting = false; while (!exiting) { @@ -981,33 +1030,30 @@ main(int argc, char *argv[]) patch_run(&ctx, br_int, chassis); encaps_run(&ctx, br_int, chassis_id); - if (ofctrl_can_put()) { - stopwatch_start(CONTROLLER_LOOP_STOPWATCH_NAME, - time_msec()); - engine_run(&en_flow_output, ++engine_run_id); - stopwatch_stop(CONTROLLER_LOOP_STOPWATCH_NAME, - time_msec()); - - if (ctx.ovs_idl_txn) { - commit_ct_zones(br_int, &ed_runtime_data.pending_ct_zones); - bfd_run(&ctx, br_int, chassis, - &ed_runtime_data.local_datapaths, - &ed_runtime_data.chassis_index); - } - if (en_flow_output.changed) { - ofctrl_put(&ed_flow_output.flow_table, - &ed_runtime_data.pending_ct_zones, - get_nb_cfg(ctx.ovnsb_idl)); - } + stopwatch_start(CONTROLLER_LOOP_STOPWATCH_NAME, + time_msec()); + engine_run(&en_flow_output, ++engine_run_id); + stopwatch_stop(CONTROLLER_LOOP_STOPWATCH_NAME, + time_msec()); + if (ctx.ovs_idl_txn) { + commit_ct_zones(br_int, &ed_runtime_data.pending_ct_zones); + bfd_run(&ctx, br_int, chassis, + &ed_runtime_data.local_datapaths, + &ed_runtime_data.chassis_index); } - + ofctrl_put(&ed_flow_output.flow_table, + &ed_runtime_data.pending_ct_zones, + get_nb_cfg(ctx.ovnsb_idl), + en_flow_output.changed); pinctrl_run(&ctx, br_int, chassis, &ed_runtime_data.chassis_index, &ed_runtime_data.local_datapaths, &ed_runtime_data.active_tunnels); - update_sb_monitors(ctx.ovnsb_idl, chassis, - &ed_runtime_data.local_lports, - &ed_runtime_data.local_datapaths); + if (en_runtime_data.changed) { + update_sb_monitors(ctx.ovnsb_idl, chassis, + &ed_runtime_data.local_lports, + &ed_runtime_data.local_datapaths); + } } if (old_engine_run_id == engine_run_id) { diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c index b3aa27a..8ae14cd 100644 --- a/ovn/controller/physical.c +++ b/ovn/controller/physical.c @@ -44,6 +44,9 @@ VLOG_DEFINE_THIS_MODULE(physical); +/* UUID to identify OF flows not associated with ovsdb rows. */ +static struct uuid *hc_uuid = NULL; + void physical_register_ovs_idl(struct ovsdb_idl *ovs_idl) { @@ -188,9 +191,10 @@ get_zone_ids(const struct sbrec_port_binding *binding, } static void -put_local_common_flows(uint32_t dp_key, uint32_t port_key, +put_local_common_flows(struct ovn_desired_flow_table *flow_table, + uint32_t dp_key, uint32_t port_key, bool nested_container, const struct zone_ids *zone_ids, - struct ofpbuf *ofpacts_p, struct hmap *flow_table) + struct ofpbuf *ofpacts_p) { struct match match; @@ -224,7 +228,7 @@ put_local_common_flows(uint32_t dp_key, uint32_t port_key, /* Resubmit to table 34. */ put_resubmit(OFTABLE_CHECK_LOOPBACK, ofpacts_p); ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 100, 0, - &match, ofpacts_p); + &match, ofpacts_p, hc_uuid); /* Table 34, Priority 100. * ======================= @@ -239,7 +243,7 @@ put_local_common_flows(uint32_t dp_key, uint32_t port_key, match_set_reg(&match, MFF_LOG_INPORT - MFF_REG0, port_key); match_set_reg(&match, MFF_LOG_OUTPORT - MFF_REG0, port_key); ofctrl_add_flow(flow_table, OFTABLE_CHECK_LOOPBACK, 100, 0, - &match, ofpacts_p); + &match, ofpacts_p, hc_uuid); /* Table 64, Priority 100. * ======================= @@ -263,7 +267,7 @@ put_local_common_flows(uint32_t dp_key, uint32_t port_key, put_resubmit(OFTABLE_LOG_TO_PHY, ofpacts_p); put_stack(MFF_IN_PORT, ofpact_put_STACK_POP(ofpacts_p)); ofctrl_add_flow(flow_table, OFTABLE_SAVE_INPORT, 100, 0, - &match, ofpacts_p); + &match, ofpacts_p, hc_uuid); } static void @@ -291,7 +295,8 @@ load_logical_ingress_metadata(const struct sbrec_port_binding *binding, } static void -consider_port_binding(struct controller_ctx *ctx, +consider_port_binding(struct ovn_desired_flow_table *flow_table, + struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, const struct simap *ct_zones, const struct chassis_index *chassis_index, @@ -299,8 +304,7 @@ consider_port_binding(struct controller_ctx *ctx, struct hmap *local_datapaths, const struct sbrec_port_binding *binding, const struct sbrec_chassis *chassis, - struct ofpbuf *ofpacts_p, - struct hmap *flow_table) + struct ofpbuf *ofpacts_p) { uint32_t dp_key = binding->datapath->tunnel_key; uint32_t port_key = binding->tunnel_key; @@ -328,8 +332,8 @@ consider_port_binding(struct controller_ctx *ctx, } struct zone_ids binding_zones = get_zone_ids(binding, ct_zones); - put_local_common_flows(dp_key, port_key, false, &binding_zones, - ofpacts_p, flow_table); + put_local_common_flows(flow_table, dp_key, port_key, false, + &binding_zones, ofpacts_p); match_init_catchall(&match); ofpbuf_clear(ofpacts_p); @@ -356,7 +360,7 @@ consider_port_binding(struct controller_ctx *ctx, ofpact_finish_CLONE(ofpacts_p, &clone); ofctrl_add_flow(flow_table, OFTABLE_LOG_TO_PHY, 100, 0, - &match, ofpacts_p); + &match, ofpacts_p, hc_uuid); return; } @@ -424,7 +428,7 @@ consider_port_binding(struct controller_ctx *ctx, } ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 100, 0, - &match, ofpacts_p); + &match, ofpacts_p, hc_uuid); goto out; } @@ -522,8 +526,8 @@ consider_port_binding(struct controller_ctx *ctx, */ struct zone_ids zone_ids = get_zone_ids(binding, ct_zones); - put_local_common_flows(dp_key, port_key, nested_container, &zone_ids, - ofpacts_p, flow_table); + put_local_common_flows(flow_table, dp_key, port_key, nested_container, + &zone_ids, ofpacts_p); /* Table 0, Priority 150 and 100. * ============================== @@ -567,7 +571,7 @@ consider_port_binding(struct controller_ctx *ctx, /* Resubmit to first logical ingress pipeline table. */ put_resubmit(OFTABLE_LOG_INGRESS_PIPELINE, ofpacts_p); ofctrl_add_flow(flow_table, OFTABLE_PHY_TO_LOG, - tag ? 150 : 100, 0, &match, ofpacts_p); + tag ? 150 : 100, 0, &match, ofpacts_p, hc_uuid); if (!tag && (!strcmp(binding->type, "localnet") || !strcmp(binding->type, "l2gateway"))) { @@ -577,7 +581,7 @@ consider_port_binding(struct controller_ctx *ctx, * action. */ ofpbuf_pull(ofpacts_p, ofpacts_orig_size); match_set_dl_tci_masked(&match, 0, htons(VLAN_CFI)); - ofctrl_add_flow(flow_table, 0, 100, 0, &match, ofpacts_p); + ofctrl_add_flow(flow_table, 0, 100, 0, &match, ofpacts_p, hc_uuid); } /* Table 65, Priority 100. @@ -605,7 +609,7 @@ consider_port_binding(struct controller_ctx *ctx, ofpact_put_STRIP_VLAN(ofpacts_p); } ofctrl_add_flow(flow_table, OFTABLE_LOG_TO_PHY, 100, 0, - &match, ofpacts_p); + &match, ofpacts_p, hc_uuid); } else if (!tun && !is_ha_remote) { /* Remote port connected by localnet port */ /* Table 33, priority 100. @@ -628,7 +632,7 @@ consider_port_binding(struct controller_ctx *ctx, /* Resubmit to table 33. */ put_resubmit(OFTABLE_LOCAL_OUTPUT, ofpacts_p); ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 100, 0, - &match, ofpacts_p); + &match, ofpacts_p, hc_uuid); } else { /* Remote port connected by tunnel */ @@ -719,7 +723,7 @@ consider_port_binding(struct controller_ctx *ctx, ofpact_finish_BUNDLE(ofpacts_p, &bundle); } ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 100, 0, - &match, ofpacts_p); + &match, ofpacts_p, hc_uuid); } out: if (gateway_chassis) { @@ -728,14 +732,14 @@ out: } static void -consider_mc_group(enum mf_field_id mff_ovn_geneve, +consider_mc_group(struct ovn_desired_flow_table *flow_table, + enum mf_field_id mff_ovn_geneve, const struct simap *ct_zones, struct hmap *local_datapaths, const struct sbrec_chassis *chassis, const struct sbrec_multicast_group *mc, struct ofpbuf *ofpacts_p, - struct ofpbuf *remote_ofpacts_p, - struct hmap *flow_table) + struct ofpbuf *remote_ofpacts_p) { uint32_t dp_key = mc->datapath->tunnel_key; if (!get_local_datapath(local_datapaths, dp_key)) { @@ -811,7 +815,7 @@ consider_mc_group(enum mf_field_id mff_ovn_geneve, put_load(mc->tunnel_key, MFF_LOG_OUTPORT, 0, 32, ofpacts_p); ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 100, 0, - &match, ofpacts_p); + &match, ofpacts_p, hc_uuid); } /* Table 32, priority 100. @@ -849,7 +853,7 @@ consider_mc_group(enum mf_field_id mff_ovn_geneve, put_resubmit(OFTABLE_LOCAL_OUTPUT, remote_ofpacts_p); } ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 100, 0, - &match, remote_ofpacts_p); + &match, remote_ofpacts_p, hc_uuid); } } sset_destroy(&remote_chassis); @@ -867,16 +871,22 @@ update_ofports(struct simap *old, struct simap *new) } void -physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, +physical_run(struct ovn_desired_flow_table *flow_table, + struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, const struct ovsrec_bridge *br_int, const struct sbrec_chassis *chassis, const struct simap *ct_zones, - struct hmap *flow_table, struct hmap *local_datapaths, + struct hmap *local_datapaths, const struct sset *local_lports, struct chassis_index *chassis_index, struct sset *active_tunnels) { + if (!hc_uuid) { + hc_uuid = xmalloc(sizeof(struct uuid)); + uuid_generate(hc_uuid); + } + /* This bool tracks physical mapping changes. */ bool physical_map_changed = false; @@ -995,10 +1005,10 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, * 64 for logical-to-physical translation. */ const struct sbrec_port_binding *binding; SBREC_PORT_BINDING_FOR_EACH (binding, ctx->ovnsb_idl) { - consider_port_binding(ctx, mff_ovn_geneve, ct_zones, + consider_port_binding(flow_table, ctx, mff_ovn_geneve, ct_zones, chassis_index, active_tunnels, local_datapaths, binding, chassis, - &ofpacts, flow_table); + &ofpacts); } /* Handle output to multicast groups, in tables 32 and 33. */ @@ -1006,8 +1016,9 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, struct ofpbuf remote_ofpacts; ofpbuf_init(&remote_ofpacts, 0); SBREC_MULTICAST_GROUP_FOR_EACH (mc, ctx->ovnsb_idl) { - consider_mc_group(mff_ovn_geneve, ct_zones, local_datapaths, chassis, - mc, &ofpacts, &remote_ofpacts, flow_table); + consider_mc_group(flow_table, mff_ovn_geneve, ct_zones, + local_datapaths, chassis, mc, &ofpacts, + &remote_ofpacts); } ofpbuf_uninit(&remote_ofpacts); @@ -1048,7 +1059,7 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, put_resubmit(OFTABLE_LOCAL_OUTPUT, &ofpacts); ofctrl_add_flow(flow_table, OFTABLE_PHY_TO_LOG, 100, 0, &match, - &ofpacts); + &ofpacts, hc_uuid); } /* Add flows for VXLAN encapsulations. Due to the limited amount of @@ -1081,7 +1092,7 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, put_resubmit(OFTABLE_LOG_INGRESS_PIPELINE, &ofpacts); ofctrl_add_flow(flow_table, OFTABLE_PHY_TO_LOG, 100, 0, &match, - &ofpacts); + &ofpacts, hc_uuid); } } @@ -1102,7 +1113,7 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, ofpbuf_clear(&ofpacts); put_resubmit(OFTABLE_LOCAL_OUTPUT, &ofpacts); ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 150, 0, - &match, &ofpacts); + &match, &ofpacts, hc_uuid); /* Table 32, priority 150. * ======================= @@ -1116,7 +1127,7 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, ofpbuf_clear(&ofpacts); put_resubmit(OFTABLE_LOCAL_OUTPUT, &ofpacts); ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 150, 0, - &match, &ofpacts); + &match, &ofpacts, hc_uuid); /* Table 32, priority 150. * ======================= @@ -1139,7 +1150,7 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, match_set_reg(&match, MFF_LOG_INPORT - MFF_REG0, pb->tunnel_key); match_set_metadata(&match, htonll(pb->datapath->tunnel_key)); ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 150, 0, - &match, &ofpacts); + &match, &ofpacts, hc_uuid); } } @@ -1151,7 +1162,8 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, match_init_catchall(&match); ofpbuf_clear(&ofpacts); put_resubmit(OFTABLE_LOCAL_OUTPUT, &ofpacts); - ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 0, 0, &match, &ofpacts); + ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 0, 0, &match, &ofpacts, + hc_uuid); /* Table 34, Priority 0. * ======================= @@ -1166,7 +1178,7 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, } put_resubmit(OFTABLE_LOG_EGRESS_PIPELINE, &ofpacts); ofctrl_add_flow(flow_table, OFTABLE_CHECK_LOOPBACK, 0, 0, &match, - &ofpacts); + &ofpacts, hc_uuid); /* Table 64, Priority 0. * ======================= @@ -1176,7 +1188,8 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, match_init_catchall(&match); ofpbuf_clear(&ofpacts); put_resubmit(OFTABLE_LOG_TO_PHY, &ofpacts); - ofctrl_add_flow(flow_table, OFTABLE_SAVE_INPORT, 0, 0, &match, &ofpacts); + ofctrl_add_flow(flow_table, OFTABLE_SAVE_INPORT, 0, 0, &match, &ofpacts, + hc_uuid); ofpbuf_uninit(&ofpacts); diff --git a/ovn/controller/physical.h b/ovn/controller/physical.h index f8dbb49..7274825 100644 --- a/ovn/controller/physical.h +++ b/ovn/controller/physical.h @@ -43,11 +43,12 @@ struct chassis_index; #define OVN_GENEVE_LEN 4 void physical_register_ovs_idl(struct ovsdb_idl *); -void physical_run(struct controller_ctx *, enum mf_field_id mff_ovn_geneve, +void physical_run(struct ovn_desired_flow_table *, + struct controller_ctx *, enum mf_field_id mff_ovn_geneve, const struct ovsrec_bridge *br_int, const struct sbrec_chassis *chassis, const struct simap *ct_zones, - struct hmap *flow_table, struct hmap *local_datapaths, + struct hmap *local_datapaths, const struct sset *local_lports, struct chassis_index *chassis_index, struct sset *active_tunnels); diff --git a/ovn/lib/actions.c b/ovn/lib/actions.c index 0669cc1..20c8267 100644 --- a/ovn/lib/actions.c +++ b/ovn/lib/actions.c @@ -1049,7 +1049,8 @@ encode_CT_LB(const struct ovnact_ct_lb *cl, recirc_table, zone_reg); } - table_id = ovn_extend_table_assign_id(ep->group_table, &ds); + table_id = ovn_extend_table_assign_id(ep->group_table, &ds, + ep->lflow_uuid); ds_destroy(&ds); if (table_id == EXT_TABLE_ID_INVALID) { return; @@ -2228,7 +2229,8 @@ encode_SET_METER(const struct ovnact_set_meter *cl, cl->rate); } - table_id = ovn_extend_table_assign_id(ep->meter_table, &ds); + table_id = ovn_extend_table_assign_id(ep->meter_table, &ds, + ep->lflow_uuid); if (table_id == EXT_TABLE_ID_INVALID) { ds_destroy(&ds); return; diff --git a/ovn/lib/extend-table.c b/ovn/lib/extend-table.c index e18713b..e4dd52a 100644 --- a/ovn/lib/extend-table.c +++ b/ovn/lib/extend-table.c @@ -17,6 +17,7 @@ #include #include "bitmap.h" #include "hash.h" +#include "lib/uuid.h" #include "openvswitch/vlog.h" #include "ovn/lib/extend-table.h" @@ -89,9 +90,10 @@ ovn_extend_table_clear(struct ovn_extend_table *table, bool existing) } } +/* Remove an entry from existing table */ void -ovn_extend_table_remove(struct ovn_extend_table *table, - struct ovn_extend_table_info *existing) +ovn_extend_table_remove_existing(struct ovn_extend_table *table, + struct ovn_extend_table_info *existing) { /* Remove 'existing' from 'groups->existing' */ hmap_remove(&table->existing, &existing->hmap_node); @@ -102,21 +104,50 @@ ovn_extend_table_remove(struct ovn_extend_table *table, free(existing); } +/* Remove entries in desired table that are created by the lflow_uuid */ void -ovn_extend_table_move(struct ovn_extend_table *table) +ovn_extend_table_remove_desired(struct ovn_extend_table *table, + const struct uuid *lflow_uuid) +{ + struct ovn_extend_table_info *e, *next_e; + HMAP_FOR_EACH_SAFE (e, next_e, hmap_node, &table->desired) { + if (uuid_equals(&e->lflow_uuid, lflow_uuid)) { + hmap_remove(&table->desired, &e->hmap_node); + ds_destroy(&e->info); + if (e->new_table_id) { + bitmap_set0(table->table_ids, e->table_id); + } + free(e); + } + } + +} + +static struct ovn_extend_table_info* +ovn_extend_info_clone(struct ovn_extend_table_info *source) +{ + struct ovn_extend_table_info *clone = xmalloc(sizeof *clone); + ds_clone(&clone->info, &source->info); + clone->table_id = source->table_id; + clone->new_table_id = source->new_table_id; + clone->hmap_node.hash = source->hmap_node.hash; + clone->lflow_uuid = source->lflow_uuid; + return clone; +} + +void +ovn_extend_table_sync(struct ovn_extend_table *table) { struct ovn_extend_table_info *desired, *next; - /* Move the contents of desired to existing. */ + /* Copy the contents of desired to existing. */ HMAP_FOR_EACH_SAFE (desired, next, hmap_node, &table->desired) { - hmap_remove(&table->desired, &desired->hmap_node); - if (!ovn_extend_table_lookup(&table->existing, desired)) { - hmap_insert(&table->existing, &desired->hmap_node, - desired->hmap_node.hash); - } else { - ds_destroy(&desired->info); - free(desired); + desired->new_table_id = false; + struct ovn_extend_table_info *clone = + ovn_extend_info_clone(desired); + hmap_insert(&table->existing, &clone->hmap_node, + clone->hmap_node.hash); } } } @@ -124,7 +155,8 @@ ovn_extend_table_move(struct ovn_extend_table *table) /* Assign a new table ID for the table information from the bitmap. * If it already exists, return the old ID. */ uint32_t -ovn_extend_table_assign_id(struct ovn_extend_table *table, struct ds *ds) +ovn_extend_table_assign_id(struct ovn_extend_table *table, struct ds *ds, + struct uuid lflow_uuid) { uint32_t table_id = 0, hash; struct ovn_extend_table_info *table_info; @@ -133,7 +165,8 @@ ovn_extend_table_assign_id(struct ovn_extend_table *table, struct ds *ds) /* Check whether we have non installed but allocated group_id. */ HMAP_FOR_EACH_WITH_HASH (table_info, hmap_node, hash, &table->desired) { - if (!strcmp(ds_cstr(&table_info->info), ds_cstr(ds))) { + if (!strcmp(ds_cstr(&table_info->info), ds_cstr(ds)) && + table_info->new_table_id) { return table_info->table_id; } } @@ -165,6 +198,7 @@ ovn_extend_table_assign_id(struct ovn_extend_table *table, struct ds *ds) table_info->table_id = table_id; table_info->hmap_node.hash = hash; table_info->new_table_id = new_table_id; + table_info->lflow_uuid = lflow_uuid; hmap_insert(&table->desired, &table_info->hmap_node, table_info->hmap_node.hash); diff --git a/ovn/lib/extend-table.h b/ovn/lib/extend-table.h index d9ae549..7473d4a 100644 --- a/ovn/lib/extend-table.h +++ b/ovn/lib/extend-table.h @@ -23,6 +23,7 @@ #include "openvswitch/dynamic-string.h" #include "openvswitch/hmap.h" #include "openvswitch/list.h" +#include "openvswitch/uuid.h" /* Used to manage expansion tables associated with Flow table, * such as the Group Table or Meter Table. */ @@ -37,6 +38,7 @@ struct ovn_extend_table { struct ovn_extend_table_info { struct hmap_node hmap_node; struct ds info; /* Details string for the table entity. */ + struct uuid lflow_uuid; uint32_t table_id; bool new_table_id; /* 'True' if 'table_id' was reserved from * ovn_extend_table's 'table_ids' bitmap. */ @@ -51,14 +53,18 @@ struct ovn_extend_table_info *ovn_extend_table_lookup( void ovn_extend_table_clear(struct ovn_extend_table *, bool); -void ovn_extend_table_remove(struct ovn_extend_table *, - struct ovn_extend_table_info *); +void ovn_extend_table_remove_existing(struct ovn_extend_table *, + struct ovn_extend_table_info *); -/* Move the contents of desired to existing. */ -void ovn_extend_table_move(struct ovn_extend_table *); +void ovn_extend_table_remove_desired(struct ovn_extend_table *, + const struct uuid *lflow_uuid); + +/* Copy the contents of desired to existing. */ +void ovn_extend_table_sync(struct ovn_extend_table *); uint32_t ovn_extend_table_assign_id(struct ovn_extend_table *, - struct ds *); + struct ds *, + struct uuid lflow_uuid); /* Iterates 'DESIRED' through all of the 'ovn_extend_table_info's in * 'TABLE'->desired that are not in 'TABLE'->existing. (The loop body From patchwork Fri Jun 1 17:41:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 924263 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=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="DKpo2G3X"; dkim-atps=neutral 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 40yBZJ4yLVz9ry1 for ; Sat, 2 Jun 2018 03:45:44 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 6FA76F3F; Fri, 1 Jun 2018 17:42:49 +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 53990F21 for ; Fri, 1 Jun 2018 17:42:47 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pf0-f169.google.com (mail-pf0-f169.google.com [209.85.192.169]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 313C1CF for ; Fri, 1 Jun 2018 17:42:45 +0000 (UTC) Received: by mail-pf0-f169.google.com with SMTP id x9-v6so12840867pfm.2 for ; Fri, 01 Jun 2018 10:42:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=H00atMnAqaRst0t72BZmvSBov+5nwsFXXQrmhtaAQ98=; b=DKpo2G3XkdEdwB1AO66Vn+NY5/IQr/2nl2b5OndbGy0OgUsrWqpefTEbDunrVo0hvd 1CHDURo29FOGS4lUMACvhwQMMw8TV+mmDakjoLsXlR267bPkQ8qG7GdtCqkNfCK6HGpx 55tSwm1GpKmdhQEBdcdTd8PrpNd5zJKcha3oaV86rD8OAsM98F7SHNHSFcRmy6y1yJkG 0PbkSMK234VTqdiAhOkINmAKGSYZtj1StE7z9zA9PpBVYBO/4XG79Twvf0skNs6uwihw qBs1/i7dxUaRC8GMXnNoIhBBQOvW7iaSeuFsyqoBvrGv4P/EhJDYtMRsdqSxvduqH0W4 ST9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=H00atMnAqaRst0t72BZmvSBov+5nwsFXXQrmhtaAQ98=; b=k+k3G9K8JaHeN8jYtWS1bajsRECzE7As9yxP4e7ag2CsNS3SC+PfmyDNcjfOAv2eae xKZqITcJY8bns56vAttZQQsqLG779rFVnptU08cSnCKnNNx9+0Vu9kdvJFttAJTxnJTd q3fWvxS193JD/M2n4/gS4jhmyPw3U1+k/FwnRoBbBEAsNozBenhqGdkkjWjNeNcn2czr oBT9TuNlur+Zp63TaoQLXVsWMSUwVx82cp1dE7hGZ0UkRDFXVbG8REm3pggBSlOoiXlC gB6HRyblSFS+yxYDgp+snvbVSYYSwACRW9fRCl33UfOINbTIvxajPXoraVSusaTLQtDx o1gQ== X-Gm-Message-State: ALKqPweqTQAwUwMlVo6HzpgPS7Hu6TX1+oj8VvtSuiLIrF4f/cidTL5P YtRzTpcvFl2kJcFBkXiYwKN8QQ== X-Google-Smtp-Source: ADUXVKLmJzv/Gal4WcXHuo7oGWRq3yLHH+zWJkkHRoodbnI+Q5KTRyx3faI6npx6c3fwXfIzBmuC7A== X-Received: by 2002:a62:5610:: with SMTP id k16-v6mr11696934pfb.19.1527874964549; Fri, 01 Jun 2018 10:42:44 -0700 (PDT) Received: from localhost.localdomain.localdomain (c-73-162-150-77.hsd1.ca.comcast.net. [73.162.150.77]) by smtp.gmail.com with ESMTPSA id v26-v6sm9600279pfe.13.2018.06.01.10.42.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 Jun 2018 10:42:44 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Fri, 1 Jun 2018 10:41:57 -0700 Message-Id: <1527874926-40450-8-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> References: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v3 07/16] ovn-controller: runtime_data change handler for SB port-binding 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 Evaluates change for SB port-binding in runtime_data node. If the port-binding change has no impact for the runtime_data it will not trigger runtime_data change. Signed-off-by: Han Zhou --- ovn/controller/binding.c | 92 +++++++++++++++++++++++++++++++++++++++++ ovn/controller/binding.h | 4 ++ ovn/controller/ovn-controller.c | 28 ++++++++++++- 3 files changed, 123 insertions(+), 1 deletion(-) diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c index 84ff4d6..0c5b47b 100644 --- a/ovn/controller/binding.c +++ b/ovn/controller/binding.c @@ -580,6 +580,98 @@ binding_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int, hmap_destroy(&qos_map); } +static bool +is_our_chassis(const struct chassis_index *chassis_index, + struct sset *active_tunnels, + const struct sbrec_chassis *chassis_rec, + const struct sbrec_port_binding *binding_rec, + struct shash *lport_to_iface, + struct sset *local_lports) +{ + const struct ovsrec_interface *iface_rec + = shash_find_data(lport_to_iface, binding_rec->logical_port); + struct ovs_list *gateway_chassis = NULL; + + bool our_chassis = false; + if (iface_rec + || (binding_rec->parent_port && binding_rec->parent_port[0] && + sset_contains(local_lports, binding_rec->parent_port))) { + /* This port is in our chassis unless it is a localport. */ + if (strcmp(binding_rec->type, "localport")) { + our_chassis = true; + } + } else if (!strcmp(binding_rec->type, "l2gateway")) { + const char *chassis_id = smap_get(&binding_rec->options, + "l2gateway-chassis"); + our_chassis = chassis_id && !strcmp(chassis_id, chassis_rec->name); + } else if (!strcmp(binding_rec->type, "chassisredirect")) { + gateway_chassis = gateway_chassis_get_ordered(binding_rec, + chassis_index); + if (gateway_chassis && + gateway_chassis_contains(gateway_chassis, chassis_rec)) { + + our_chassis = gateway_chassis_is_active( + gateway_chassis, chassis_rec, active_tunnels); + + } + gateway_chassis_destroy(gateway_chassis); + } else if (!strcmp(binding_rec->type, "l3gateway")) { + const char *chassis_id = smap_get(&binding_rec->options, + "l3gateway-chassis"); + our_chassis = chassis_id && !strcmp(chassis_id, chassis_rec->name); + } else if (!strcmp(binding_rec->type, "localnet")) { + our_chassis = false; + } + + return our_chassis; +} + +/* Returns true if port-binding changes potentially require flow changes on + * the current chassis. Returns false if we are sure there is no impact. */ +bool +binding_evaluate_port_binding_changes( + struct controller_ctx *ctx, const struct ovsrec_bridge *br_int, + const struct sbrec_chassis *chassis_rec, + const struct chassis_index *chassis_index, + struct sset *active_tunnels, + struct sset *local_lports) +{ + if (!chassis_rec) { + return true; + } + + const struct sbrec_port_binding *binding_rec; + struct shash lport_to_iface = SHASH_INITIALIZER(&lport_to_iface); + struct sset egress_ifaces = SSET_INITIALIZER(&egress_ifaces); + if (br_int) { + get_local_iface_ids(br_int, &lport_to_iface, local_lports, + &egress_ifaces); + } + SBREC_PORT_BINDING_FOR_EACH_TRACKED (binding_rec, ctx->ovnsb_idl) { + /* XXX: currently OVSDB change tracking doesn't support getting old + * data when the operation is update, so if a port-binding moved from + * this chassis to another, we would not know it with this check. + * However, if the port is unbound from this chassis, the local ovsdb + * interface table will be updated, which will trigger recompute. + * If the port is still bound on this chassis, then below check + * is_our_chassis() will take care that case. */ + if (binding_rec->chassis == chassis_rec) { + return true; + } + if (is_our_chassis(chassis_index, + active_tunnels, chassis_rec, binding_rec, + &lport_to_iface, + local_lports) + || !strcmp(binding_rec->type, "patch") + || !strcmp(binding_rec->type, "localport") + || !strcmp(binding_rec->type, "vtep") + || !strcmp(binding_rec->type, "localnet")) { + return true; + } + } + return false; +} + /* Returns true if the database is all cleaned up, false if more work is * required. */ bool diff --git a/ovn/controller/binding.h b/ovn/controller/binding.h index 89fc2ec..ea4fb81 100644 --- a/ovn/controller/binding.h +++ b/ovn/controller/binding.h @@ -34,5 +34,9 @@ void binding_run(struct controller_ctx *, const struct ovsrec_bridge *br_int, struct sset *active_tunnels, struct hmap *local_datapaths, struct sset *local_lports, struct sset *local_lport_ids); bool binding_cleanup(struct controller_ctx *, const struct sbrec_chassis *); +bool binding_evaluate_port_binding_changes( + struct controller_ctx *ctx, const struct ovsrec_bridge *br_int, + const struct sbrec_chassis *, const struct chassis_index *, + struct sset *active_tunnels, struct sset *local_lports); #endif /* ovn/binding.h */ diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 7f81c93..215146b 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -745,6 +745,32 @@ en_runtime_data_run(struct engine_node *node) node->changed = true; } +static bool +runtime_data_sb_port_binding_handler(struct engine_node *node) +{ + struct controller_ctx *ctx = (struct controller_ctx *)node->context; + struct ed_type_runtime_data *data = + (struct ed_type_runtime_data *)node->data; + struct sset *local_lports = &data->local_lports; + struct sset *active_tunnels = &data->active_tunnels; + struct chassis_index *chassis_index = &data->chassis_index; + + const char *chassis_id = get_chassis_id(ctx->ovs_idl); + const struct ovsrec_bridge *br_int = get_br_int(ctx); + + ovs_assert(br_int && chassis_id); + const struct sbrec_chassis *chassis = NULL; + chassis = get_chassis(ctx->ovnsb_idl, chassis_id); + ovs_assert(chassis); + + bool changed = binding_evaluate_port_binding_changes( + ctx, br_int, chassis, + chassis_index, active_tunnels, + local_lports); + + return !changed; +} + struct ed_type_flow_output { /* desired flows */ struct ovn_desired_flow_table flow_table; @@ -977,7 +1003,7 @@ main(int argc, char *argv[]) engine_add_input(&en_runtime_data, &en_sb_address_set, NULL); engine_add_input(&en_runtime_data, &en_sb_port_group, NULL); engine_add_input(&en_runtime_data, &en_sb_datapath_binding, NULL); - engine_add_input(&en_runtime_data, &en_sb_port_binding, NULL); + engine_add_input(&en_runtime_data, &en_sb_port_binding, runtime_data_sb_port_binding_handler); engine_add_input(&en_runtime_data, &en_sb_gateway_chassis, NULL); engine_init(&en_flow_output); From patchwork Fri Jun 1 17:41:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 924264 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=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="FCRyaP0H"; dkim-atps=neutral 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 40yBZx55Llz9ry1 for ; Sat, 2 Jun 2018 03:46:17 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 442D8F46; Fri, 1 Jun 2018 17:42:51 +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 363C6F22 for ; Fri, 1 Jun 2018 17:42:48 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg0-f42.google.com (mail-pg0-f42.google.com [74.125.83.42]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 128556D8 for ; Fri, 1 Jun 2018 17:42:47 +0000 (UTC) Received: by mail-pg0-f42.google.com with SMTP id w12-v6so10360646pgc.6 for ; Fri, 01 Jun 2018 10:42:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xeNco84uWmBqWx03Qh9Tzz42Vu0XMgSLTchkGYPv1os=; b=FCRyaP0Hp0yajusIex32WQcjSUGTeJ7YXBWFVNWjrVO8HuTkWsDYZCgY7G9IYPw1bq nQVlYeWvHDvGtCBOmDaLhzlnQDisg2rrcXaDLL6Sv1f9nQ4pD2Umh3TFRSfMthAUIhBa NccrIMx6jn+95eyQ/wtAmvH3W4CdDUaz7f+gSkHnRGQfzZ+kSbPMlERQBvVUfJ/kA+Bd iD5cNb8lnIyxZ0GBX9DMx9CDEfCuRVqgwgpvULp9+METTXHdZnfSpRkcUi+KgxweJzZL ZsCJZoJftzu19EpGHOFyT6xboB+I9bBXWDmQwkgXP22jq4dE+oN419N7qFD762Recf23 3kPQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=xeNco84uWmBqWx03Qh9Tzz42Vu0XMgSLTchkGYPv1os=; b=UO3z8GAr/BCKl7zHV9AoLC9efm+kVhiM/8gel1JLWRowE+8AvYDseKZk7O92jQf+mM Naeu2FxiWzWU5DxNoONhm0VK16ZnpeecRyr6PhxOfNuwsROYdjUhT8KVzY+GhAijNxrl 6wTrQqR4CFr+/cI8Y9urHo6icgrD+V9zBnjg9Q37+vdTVvjKVhDby+YHpU7/2tp2/WMh KCVauz04Djdt6qXBYwBTzTFcmBvv3ddtH9o7kN5P9nZ+QaNb+UxDJusNXEwWf//Q/hvl 4kRZ+nfxeD2IE9+Tw4hqYQrDxsGK/rvVlLPdUV24ifZak0PTFTJOzDfQxdTYOdzA17X7 mvtw== X-Gm-Message-State: ALKqPweTGmhBGQNKHwBPzFmcb+sC7hcPYF9+BmAJ7wcphPe7glW0oouz s0ikQk4MD7/6aOsGDqVkFWtS1g== X-Google-Smtp-Source: ADUXVKIoWCK2Govsp5ECasx5d/NohRxWPi21cMZROUvBrTrTtsN9//8Bp1+ciVxyYYSpgJJhFH8HYA== X-Received: by 2002:a62:b509:: with SMTP id y9-v6mr9505807pfe.121.1527874966264; Fri, 01 Jun 2018 10:42:46 -0700 (PDT) Received: from localhost.localdomain.localdomain (c-73-162-150-77.hsd1.ca.comcast.net. [73.162.150.77]) by smtp.gmail.com with ESMTPSA id v26-v6sm9600279pfe.13.2018.06.01.10.42.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 Jun 2018 10:42:45 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Fri, 1 Jun 2018 10:41:58 -0700 Message-Id: <1527874926-40450-9-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> References: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v3 08/16] ovn-controller: port-binding incremental processing for physical flows 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 This patch implements change handler for port-binding in flow_output for physical flows computing, so that physical flow computing will be incremental. This patch together with previous incremental processing engine related changes supports incremental processing for lflow changes and port-binding changes of lports on other HVs, which are the most common scenarios in a cloud where workloads come up and down. In ovn-scale-test env [1], the total execution time of creating and binding 10k ports on 1k HVs with 40 lswitches and 8 lrouters (5 lswitches/lrouter), decreased from 3h40m to 1h50m because of the less CPU on HVs. The CPU time of ovn-controller for additional 500 lports creating and binding (on top of already existed 10k lports) decreased 90% comparing with master. Latency for end-to-end operations of one extra port on top of the 10k lports, start from port-creation until all flows installation on all related HVs is also improved significantly from 20.6s to 7.3s. [1] https://github.com/openvswitch/ovn-scale-test Signed-off-by: Han Zhou --- ovn/controller/ovn-controller.c | 76 ++++++++++++++++++++++- ovn/controller/physical.c | 129 +++++++++++++++++++++++++++++----------- ovn/controller/physical.h | 8 +++ 3 files changed, 178 insertions(+), 35 deletions(-) diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 215146b..e939d03 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -903,6 +903,80 @@ flow_output_sb_logical_flow_handler(struct engine_node *node) return handled; } +static bool +flow_output_sb_port_binding_handler(struct engine_node *node) +{ + struct controller_ctx *ctx = (struct controller_ctx *)node->context; + struct ed_type_runtime_data *data = + (struct ed_type_runtime_data *)engine_get_input( + "runtime_data", node)->data; + struct hmap *local_datapaths = &data->local_datapaths; + struct sset *active_tunnels = &data->active_tunnels; + struct chassis_index *chassis_index = &data->chassis_index; + struct simap *ct_zones = &data->ct_zones; + const struct ovsrec_bridge *br_int = get_br_int(ctx); + + const char *chassis_id = get_chassis_id(ctx->ovs_idl); + + + const struct sbrec_chassis *chassis = NULL; + if (chassis_id) { + chassis = get_chassis(ctx->ovnsb_idl, chassis_id); + } + + ovs_assert(br_int && chassis); + + struct ed_type_flow_output *fo = + (struct ed_type_flow_output *)node->data; + struct ovn_desired_flow_table *flow_table = &fo->flow_table; + + /* XXX: now we handles port-binding changes for physical flow processing + * only, but port-binding change can have impact to logical flow + * processing, too, in below circumstances: + * + * - When a port-binding for a lport is inserted/deleted but the lflow + * using that lport doesn't change. + * + * This is likely to happen only when the lport name is used by ACL + * match condition, which is specified by user. Even in that case, when + * port is actually bound on the chassis it will trigger recompute on + * that chassis since ovs interface is updated. So the only situation + * this would have real impact is when user defines an ACL that includes + * lport that is not the ingress/egress lport, e.g.: + * + * to-lport 1000 'outport=="A" && inport=="B"' allow-related + * + * If "B" is created and bound after the ACL is created, the ACL may not + * take effect on the chassis where "A" is bound, until a recompute is + * triggered there later. + * + * - When is_chassis_resident is used in lflow. In this case the port + * binding is patch type, since this condition is used only for lrouter + * ports. In current "runtime_data" handling, port-binding changes of + * patch ports always trigger recomputing. So it is fine even if we do + * not handle it here. + * + * - When a mac-binding doesn't change but the port-binding related to + * that mac-binding is deleted. In this case the neighbor flow generated + * for the mac-binding should be deleted. This would not cause any real + * issue for now, since mac-binding change triggers recomputing. + * + * To address the above issues, we will need to maintain a mapping between + * lport names and the lflows that uses them, and reprocess the related + * lflows when a port-binding corresponding to a lport name changes. + */ + + enum mf_field_id mff_ovn_geneve = ofctrl_get_mf_field_id(); + physical_handle_port_binding_changes(flow_table, + ctx, mff_ovn_geneve, + chassis, ct_zones, + local_datapaths, + chassis_index, active_tunnels); + + node->changed = true; + return true; +} + int main(int argc, char *argv[]) { @@ -988,7 +1062,7 @@ main(int argc, char *argv[]) engine_add_input(&en_flow_output, &en_sb_encap, NULL); engine_add_input(&en_flow_output, &en_sb_multicast_group, NULL); engine_add_input(&en_flow_output, &en_sb_datapath_binding, NULL); - engine_add_input(&en_flow_output, &en_sb_port_binding, NULL); + engine_add_input(&en_flow_output, &en_sb_port_binding, flow_output_sb_port_binding_handler); engine_add_input(&en_flow_output, &en_sb_mac_binding, NULL); engine_add_input(&en_flow_output, &en_sb_logical_flow, flow_output_sb_logical_flow_handler); engine_add_input(&en_flow_output, &en_sb_dhcp_options, NULL); diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c index 8ae14cd..d860686 100644 --- a/ovn/controller/physical.c +++ b/ovn/controller/physical.c @@ -360,7 +360,7 @@ consider_port_binding(struct ovn_desired_flow_table *flow_table, ofpact_finish_CLONE(ofpacts_p, &clone); ofctrl_add_flow(flow_table, OFTABLE_LOG_TO_PHY, 100, 0, - &match, ofpacts_p, hc_uuid); + &match, ofpacts_p, &binding->header_.uuid); return; } @@ -428,7 +428,7 @@ consider_port_binding(struct ovn_desired_flow_table *flow_table, } ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 100, 0, - &match, ofpacts_p, hc_uuid); + &match, ofpacts_p, &binding->header_.uuid); goto out; } @@ -571,7 +571,8 @@ consider_port_binding(struct ovn_desired_flow_table *flow_table, /* Resubmit to first logical ingress pipeline table. */ put_resubmit(OFTABLE_LOG_INGRESS_PIPELINE, ofpacts_p); ofctrl_add_flow(flow_table, OFTABLE_PHY_TO_LOG, - tag ? 150 : 100, 0, &match, ofpacts_p, hc_uuid); + tag ? 150 : 100, 0, &match, ofpacts_p, + &binding->header_.uuid); if (!tag && (!strcmp(binding->type, "localnet") || !strcmp(binding->type, "l2gateway"))) { @@ -581,7 +582,8 @@ consider_port_binding(struct ovn_desired_flow_table *flow_table, * action. */ ofpbuf_pull(ofpacts_p, ofpacts_orig_size); match_set_dl_tci_masked(&match, 0, htons(VLAN_CFI)); - ofctrl_add_flow(flow_table, 0, 100, 0, &match, ofpacts_p, hc_uuid); + ofctrl_add_flow(flow_table, 0, 100, 0, &match, ofpacts_p, + &binding->header_.uuid); } /* Table 65, Priority 100. @@ -609,7 +611,7 @@ consider_port_binding(struct ovn_desired_flow_table *flow_table, ofpact_put_STRIP_VLAN(ofpacts_p); } ofctrl_add_flow(flow_table, OFTABLE_LOG_TO_PHY, 100, 0, - &match, ofpacts_p, hc_uuid); + &match, ofpacts_p, &binding->header_.uuid); } else if (!tun && !is_ha_remote) { /* Remote port connected by localnet port */ /* Table 33, priority 100. @@ -632,7 +634,7 @@ consider_port_binding(struct ovn_desired_flow_table *flow_table, /* Resubmit to table 33. */ put_resubmit(OFTABLE_LOCAL_OUTPUT, ofpacts_p); ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 100, 0, - &match, ofpacts_p, hc_uuid); + &match, ofpacts_p, &binding->header_.uuid); } else { /* Remote port connected by tunnel */ @@ -723,7 +725,7 @@ consider_port_binding(struct ovn_desired_flow_table *flow_table, ofpact_finish_BUNDLE(ofpacts_p, &bundle); } ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 100, 0, - &match, ofpacts_p, hc_uuid); + &match, ofpacts_p, &binding->header_.uuid); } out: if (gateway_chassis) { @@ -737,9 +739,7 @@ consider_mc_group(struct ovn_desired_flow_table *flow_table, const struct simap *ct_zones, struct hmap *local_datapaths, const struct sbrec_chassis *chassis, - const struct sbrec_multicast_group *mc, - struct ofpbuf *ofpacts_p, - struct ofpbuf *remote_ofpacts_p) + const struct sbrec_multicast_group *mc) { uint32_t dp_key = mc->datapath->tunnel_key; if (!get_local_datapath(local_datapaths, dp_key)) { @@ -765,8 +765,10 @@ consider_mc_group(struct ovn_desired_flow_table *flow_table, * would happen on every hypervisor in the multicast group, * effectively duplicating the packet.) */ - ofpbuf_clear(ofpacts_p); - ofpbuf_clear(remote_ofpacts_p); + struct ofpbuf ofpacts; + ofpbuf_init(&ofpacts, 0); + struct ofpbuf remote_ofpacts; + ofpbuf_init(&remote_ofpacts, 0); for (size_t i = 0; i < mc->n_ports; i++) { struct sbrec_port_binding *port = mc->ports[i]; @@ -780,20 +782,20 @@ consider_mc_group(struct ovn_desired_flow_table *flow_table, int zone_id = simap_get(ct_zones, port->logical_port); if (zone_id) { - put_load(zone_id, MFF_LOG_CT_ZONE, 0, 32, ofpacts_p); + put_load(zone_id, MFF_LOG_CT_ZONE, 0, 32, &ofpacts); } if (!strcmp(port->type, "patch")) { put_load(port->tunnel_key, MFF_LOG_OUTPORT, 0, 32, - remote_ofpacts_p); - put_resubmit(OFTABLE_CHECK_LOOPBACK, remote_ofpacts_p); + &remote_ofpacts); + put_resubmit(OFTABLE_CHECK_LOOPBACK, &remote_ofpacts); } else if (simap_contains(&localvif_to_ofport, (port->parent_port && *port->parent_port) ? port->parent_port : port->logical_port) || (!strcmp(port->type, "l3gateway") && port->chassis == chassis)) { - put_load(port->tunnel_key, MFF_LOG_OUTPORT, 0, 32, ofpacts_p); - put_resubmit(OFTABLE_CHECK_LOOPBACK, ofpacts_p); + put_load(port->tunnel_key, MFF_LOG_OUTPORT, 0, 32, &ofpacts); + put_resubmit(OFTABLE_CHECK_LOOPBACK, &ofpacts); } else if (port->chassis && !get_localnet_port(local_datapaths, mc->datapath->tunnel_key)) { /* Add remote chassis only when localnet port not exist, @@ -808,14 +810,14 @@ consider_mc_group(struct ovn_desired_flow_table *flow_table, * * Handle output to the local logical ports in the multicast group, if * any. */ - bool local_ports = ofpacts_p->size > 0; + bool local_ports = ofpacts.size > 0; if (local_ports) { /* Following delivery to local logical ports, restore the multicast * group as the logical output port. */ - put_load(mc->tunnel_key, MFF_LOG_OUTPORT, 0, 32, ofpacts_p); + put_load(mc->tunnel_key, MFF_LOG_OUTPORT, 0, 32, &ofpacts); ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 100, 0, - &match, ofpacts_p, hc_uuid); + &match, &ofpacts, &mc->header_.uuid); } /* Table 32, priority 100. @@ -823,12 +825,12 @@ consider_mc_group(struct ovn_desired_flow_table *flow_table, * * Handle output to the remote chassis in the multicast group, if * any. */ - if (!sset_is_empty(&remote_chassis) || remote_ofpacts_p->size > 0) { - if (remote_ofpacts_p->size > 0) { + if (!sset_is_empty(&remote_chassis) || remote_ofpacts.size > 0) { + if (remote_ofpacts.size > 0) { /* Following delivery to logical patch ports, restore the * multicast group as the logical output port. */ put_load(mc->tunnel_key, MFF_LOG_OUTPORT, 0, 32, - remote_ofpacts_p); + &remote_ofpacts); } const char *chassis_name; @@ -842,20 +844,22 @@ consider_mc_group(struct ovn_desired_flow_table *flow_table, if (!prev || tun->type != prev->type) { put_encapsulation(mff_ovn_geneve, tun, mc->datapath, - mc->tunnel_key, remote_ofpacts_p); + mc->tunnel_key, &remote_ofpacts); prev = tun; } - ofpact_put_OUTPUT(remote_ofpacts_p)->port = tun->ofport; + ofpact_put_OUTPUT(&remote_ofpacts)->port = tun->ofport; } - if (remote_ofpacts_p->size) { + if (remote_ofpacts.size) { if (local_ports) { - put_resubmit(OFTABLE_LOCAL_OUTPUT, remote_ofpacts_p); + put_resubmit(OFTABLE_LOCAL_OUTPUT, &remote_ofpacts); } ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 100, 0, - &match, remote_ofpacts_p, hc_uuid); + &match, &remote_ofpacts, &mc->header_.uuid); } } + ofpbuf_uninit(&ofpacts); + ofpbuf_uninit(&remote_ofpacts); sset_destroy(&remote_chassis); } @@ -870,6 +874,68 @@ update_ofports(struct simap *old, struct simap *new) return changed; } +static void +reconsider_mc_group_for_pb(struct ovn_desired_flow_table *flow_table, + struct controller_ctx *ctx, + const struct sbrec_port_binding *pb, + const char *mc_name, + enum mf_field_id mff_ovn_geneve, + const struct sbrec_chassis *chassis, + const struct simap *ct_zones, + struct hmap *local_datapaths) +{ + const struct sbrec_multicast_group *mc + = mcgroup_lookup_by_dp_name(ctx->ovnsb_idl, pb->datapath, mc_name); + if (mc) { + ofctrl_remove_flows(flow_table, &mc->header_.uuid); + + consider_mc_group(flow_table, mff_ovn_geneve, ct_zones, + local_datapaths, chassis, mc); + } else { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); + VLOG_WARN_RL(&rl, "MC group %s is not found in datapath: "UUID_FMT, + mc_name, UUID_ARGS(&pb->datapath->header_.uuid)); + } +} + +void +physical_handle_port_binding_changes(struct ovn_desired_flow_table *flow_table, + struct controller_ctx *ctx, + enum mf_field_id mff_ovn_geneve, + const struct sbrec_chassis *chassis, + const struct simap *ct_zones, + struct hmap *local_datapaths, + struct chassis_index *chassis_index, + struct sset *active_tunnels) +{ + const struct sbrec_port_binding *binding; + struct ofpbuf ofpacts; + ofpbuf_init(&ofpacts, 0); + SBREC_PORT_BINDING_FOR_EACH_TRACKED (binding, ctx->ovnsb_idl) { + if (sbrec_port_binding_is_deleted(binding)) { + ofctrl_remove_flows(flow_table, &binding->header_.uuid); + } else { + if (!sbrec_port_binding_is_new(binding)) { + ofctrl_remove_flows(flow_table, &binding->header_.uuid); + + reconsider_mc_group_for_pb(flow_table, + ctx, binding, "_MC_flood", + mff_ovn_geneve, chassis, + ct_zones, local_datapaths); + reconsider_mc_group_for_pb(flow_table, + ctx, binding, "_MC_unknown", + mff_ovn_geneve, chassis, + ct_zones, local_datapaths); + } + consider_port_binding(flow_table, ctx, mff_ovn_geneve, ct_zones, + chassis_index, active_tunnels, + local_datapaths, binding, chassis, + &ofpacts); + } + } + +} + void physical_run(struct ovn_desired_flow_table *flow_table, struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, @@ -1013,16 +1079,11 @@ physical_run(struct ovn_desired_flow_table *flow_table, /* Handle output to multicast groups, in tables 32 and 33. */ const struct sbrec_multicast_group *mc; - struct ofpbuf remote_ofpacts; - ofpbuf_init(&remote_ofpacts, 0); SBREC_MULTICAST_GROUP_FOR_EACH (mc, ctx->ovnsb_idl) { consider_mc_group(flow_table, mff_ovn_geneve, ct_zones, - local_datapaths, chassis, mc, &ofpacts, - &remote_ofpacts); + local_datapaths, chassis, mc); } - ofpbuf_uninit(&remote_ofpacts); - /* Table 0, priority 100. * ====================== * diff --git a/ovn/controller/physical.h b/ovn/controller/physical.h index 7274825..88c5cda 100644 --- a/ovn/controller/physical.h +++ b/ovn/controller/physical.h @@ -52,5 +52,13 @@ void physical_run(struct ovn_desired_flow_table *, const struct sset *local_lports, struct chassis_index *chassis_index, struct sset *active_tunnels); +void physical_handle_port_binding_changes(struct ovn_desired_flow_table *, + struct controller_ctx *, + enum mf_field_id mff_ovn_geneve, + const struct sbrec_chassis *, + const struct simap *ct_zones, + struct hmap *local_datapaths, + struct chassis_index *, + struct sset *active_tunnels); #endif /* ovn/physical.h */ From patchwork Fri Jun 1 17:41:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 924265 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=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="kCTH6FLI"; dkim-atps=neutral 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 40yBbc1nvxz9ry1 for ; Sat, 2 Jun 2018 03:46:52 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id B4B69F36; Fri, 1 Jun 2018 17:42:52 +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 1514AE74 for ; Fri, 1 Jun 2018 17:42:48 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f44.google.com (mail-pl0-f44.google.com [209.85.160.44]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id BDC32136 for ; Fri, 1 Jun 2018 17:42:47 +0000 (UTC) Received: by mail-pl0-f44.google.com with SMTP id az12-v6so15720632plb.8 for ; Fri, 01 Jun 2018 10:42:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xcqerSd0tsC/tFKcTGh7LOOCM8rBjsujOAwcnvR7dJc=; b=kCTH6FLIobZGHnigC9+YzQ+oTNhsu61eg+CYux4DAKEKhiyHmiS7DYrnYJo1SPxesu Cl8V31gORjKqo5OIyiiPDi+tHZSGSVrPv4xi0tkQJSOPBj6q/d/1VfQGTKe2QR3I/ah2 wLnM7kECsUhheu1GkxyuxO99NiiI82bnTeshqY9c5hp88KNhhNb4pnOBZT9b6OXxK2c9 rUp8HkrcJqaPdtX+9ONivV/ZxtE/kGxUuSbe9u2Q2zYovUb4SLiNJonmLRkvABUSrEA/ I0a9+bezPeNIv5xAQgkhlBbtud3DyqCHIJIuzXKPRrqgwvhLM3xAJB/zhUOMNyy1466n UvOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=xcqerSd0tsC/tFKcTGh7LOOCM8rBjsujOAwcnvR7dJc=; b=drAfcdfmNQzczKqd2vyrt8Llev0N/vIPp+aNQVDGNcyJXnRZgHoP2cRrMzsE0giZve TK4hwOOakQaBn8CGOTngbrD4j/uRngzvJvF7wt7AsDoyEFyvyTzE4845dBpHIrXE7xyD APK4mGoCAKqe8HkRy/LtW8cqtjFpobxyvoxiZWWtm7vkQ8wQWYzZvutCLLHl3kqjGVJo cFAFTblTj449CbC4iaW72O5rAvdtojvaicj9kTy+Z52pQJBwykU4VI6ucXt9XHFWhFMF BjGaPQwmsyOP306UIcR8tHbVtpdXANKuQBaaK4D1cSJl/h8ftocqfVpieg3EeIWEhXhS PuOA== X-Gm-Message-State: ALKqPwcHZRwlAQSkpew5qDJHQ7Ybh+1t9rSiSlk5wTcJXJXCpJ7ABQvF EjvqHryDvtNZkCgLXK8N8VNB+g== X-Google-Smtp-Source: ADUXVKLCntQViB5zo76F/PoBAcXSYF+QYZFctgzLV4PQPkS4MVdfvb53/iP8uOhNSf+LpXFRC6Kucw== X-Received: by 2002:a17:902:265:: with SMTP id 92-v6mr11770571plc.368.1527874967151; Fri, 01 Jun 2018 10:42:47 -0700 (PDT) Received: from localhost.localdomain.localdomain (c-73-162-150-77.hsd1.ca.comcast.net. [73.162.150.77]) by smtp.gmail.com with ESMTPSA id v26-v6sm9600279pfe.13.2018.06.01.10.42.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 Jun 2018 10:42:46 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Fri, 1 Jun 2018 10:41:59 -0700 Message-Id: <1527874926-40450-10-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> References: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v3 09/16] ovn-controller: Avoid forced recompute when not needed 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: Han Zhou --- ovn/controller/ovn-controller.c | 13 +++++++++---- ovn/lib/inc-proc-eng.c | 20 ++++++++++++++++++++ ovn/lib/inc-proc-eng.h | 4 ++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index e939d03..e4506c2 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -1157,10 +1157,15 @@ main(int argc, char *argv[]) } if (old_engine_run_id == engine_run_id) { - VLOG_DBG("engine did not run, force recompute next time: " - "br_int %p, chassis %p", br_int, chassis); - engine_set_force_recompute(true); - poll_immediate_wake(); + if (engine_need_run(&en_flow_output)) { + VLOG_DBG("engine did not run, force recompute next time: " + "br_int %p, chassis %p", br_int, chassis); + engine_set_force_recompute(true); + poll_immediate_wake(); + } else { + VLOG_DBG("engine did not run, and it was not needed either: " + "br_int %p, chassis %p", br_int, chassis); + } } else { engine_set_force_recompute(false); } diff --git a/ovn/lib/inc-proc-eng.c b/ovn/lib/inc-proc-eng.c index 8006acd..08f152e 100644 --- a/ovn/lib/inc-proc-eng.c +++ b/ovn/lib/inc-proc-eng.c @@ -139,3 +139,23 @@ engine_run(struct engine_node *node, uint64_t run_id) VLOG_DBG("node: %s, changed: %d", node->name, node->changed); } + +bool +engine_need_run(struct engine_node *node) +{ + size_t i; + + if (!node->n_inputs) { + node->run(node); + VLOG_DBG("input node: %s, changed: %d", node->name, node->changed); + return node->changed; + } + + for (i = 0; i < node->n_inputs; i++) { + if (engine_need_run(node->inputs[i].node)) { + return true; + } + } + + return false; +} diff --git a/ovn/lib/inc-proc-eng.h b/ovn/lib/inc-proc-eng.h index 8399321..17006f1 100644 --- a/ovn/lib/inc-proc-eng.h +++ b/ovn/lib/inc-proc-eng.h @@ -126,6 +126,10 @@ void engine_run(struct engine_node *, uint64_t run_id); * terminates. */ void engine_cleanup(struct engine_node *); +/* Check if engine needs to run, i.e. any change to be processed. */ +bool +engine_need_run(struct engine_node *); + /* Get the input node with for */ struct engine_node * engine_get_input(const char *input_name, struct engine_node *); From patchwork Fri Jun 1 17:42:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 924267 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=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="bPswgGIs"; dkim-atps=neutral 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 40yBcq5pQ3z9ry1 for ; Sat, 2 Jun 2018 03:47:55 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 178A5F5E; Fri, 1 Jun 2018 17:42:55 +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 9C74EEF5 for ; Fri, 1 Jun 2018 17:42:49 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pf0-f174.google.com (mail-pf0-f174.google.com [209.85.192.174]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id C336E136 for ; Fri, 1 Jun 2018 17:42:48 +0000 (UTC) Received: by mail-pf0-f174.google.com with SMTP id f189-v6so12843291pfa.7 for ; Fri, 01 Jun 2018 10:42:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=JiQ9z3IYDmVjSSeffF9sCPm9eqbkAQGlHhGlrgdcXRE=; b=bPswgGIsp7Myr6D9XD8Tu/PvMWwyz8X2bDd51E/4pep7XQI2GQdH7ysixpMNLI5ac+ QlM39Mx1F2nq4PYuLJZFj0eG7gNOPPjs+o2ZEfSwNKbaiSoGOC2fbqvc2Cde0TvQe8s8 xI1MwSc4dw6Wrjh+nUzF4jlKpqDL95wMBooDvvDevnSrXT20Cu60rtlYmSzpylsE8sKo ZsDjqePZ9Cyyhg3MoCs3uMG+ZLgGUpx2Up0AJtqohbpQ4rf+MFSKu6EVrm6G3yZyrqEw T0bIvE9ZgcAwXrGxdgQK6XPBOLUdzpKD8oOsK8j4TsySSR6GXV3vGFJlWotnR6ZwIS4h 8+6A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=JiQ9z3IYDmVjSSeffF9sCPm9eqbkAQGlHhGlrgdcXRE=; b=K/2vOD5t5lQOQ8F8QkCcwDKM/kI13K+yd8P+bRoQX0P+Y06q+MlSNOteUWjr1YxHvI M/T2InUe54IZB/NY3yoQTdg1U9jKv344Tb4GoS/1T18XEACPmb7eRldU0DAJhy4w345j N8A981MJpRt4InNXPP3Pqsdtr0WjwBc7+JjTZXHfPIfYz2wWDWeZxXYwj4ANVgu3E6M5 VVkBDn/QNAXYIOC2owA62bJ+B/cnsVzWcFBhHWcCT97NY53lDQipihTzY7yEPkbB+ixa 29tiEVMsycU1/NtTQN1tkUq0AqBwcTfjWUWwU45rBrLAWZFK1h+n1yyAfyUQBl1IG0Yh 5NJw== X-Gm-Message-State: ALKqPwcLgvFPUy343s242fk32mY6G9T+GM3Xa8/xim3wUDceDqEZYJgP tEcHD91IogtPrmB11SZ2yNufWQ== X-Google-Smtp-Source: ADUXVKJEiucm9Z6XLqG8yFL8xmSkrGOVEYSlhDCuqNWOEmaCIitJAEE6wjeroRNagIDE7aGDPzfUPw== X-Received: by 2002:aa7:8254:: with SMTP id e20-v6mr11873044pfn.140.1527874968168; Fri, 01 Jun 2018 10:42:48 -0700 (PDT) Received: from localhost.localdomain.localdomain (c-73-162-150-77.hsd1.ca.comcast.net. [73.162.150.77]) by smtp.gmail.com with ESMTPSA id v26-v6sm9600279pfe.13.2018.06.01.10.42.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 Jun 2018 10:42:47 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Fri, 1 Jun 2018 10:42:00 -0700 Message-Id: <1527874926-40450-11-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> References: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v3 10/16] ovn-controller: incremental processing for multicast group changes 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: Han Zhou --- ovn/controller/ovn-controller.c | 37 ++++++++++++++++++++++++++++++++++++- ovn/controller/physical.c | 23 +++++++++++++++++++++++ ovn/controller/physical.h | 7 ++++++- 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index e4506c2..56902ff 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -977,6 +977,41 @@ flow_output_sb_port_binding_handler(struct engine_node *node) return true; } +static bool +flow_output_sb_multicast_group_handler(struct engine_node *node) +{ + struct controller_ctx *ctx = (struct controller_ctx *)node->context; + struct ed_type_runtime_data *data = + (struct ed_type_runtime_data *)engine_get_input( + "runtime_data", node)->data; + struct hmap *local_datapaths = &data->local_datapaths; + struct simap *ct_zones = &data->ct_zones; + const struct ovsrec_bridge *br_int = get_br_int(ctx); + + const char *chassis_id = get_chassis_id(ctx->ovs_idl); + + + const struct sbrec_chassis *chassis = NULL; + if (chassis_id) { + chassis = get_chassis(ctx->ovnsb_idl, chassis_id); + } + + ovs_assert(br_int && chassis); + + struct ed_type_flow_output *fo = + (struct ed_type_flow_output *)node->data; + struct ovn_desired_flow_table *flow_table = &fo->flow_table; + + enum mf_field_id mff_ovn_geneve = ofctrl_get_mf_field_id(); + physical_handle_mc_group_changes(flow_table, + ctx, mff_ovn_geneve, + chassis, ct_zones, + local_datapaths); + node->changed = true; + return true; + +} + int main(int argc, char *argv[]) { @@ -1060,7 +1095,7 @@ main(int argc, char *argv[]) engine_add_input(&en_flow_output, &en_sb_chassis, NULL); engine_add_input(&en_flow_output, &en_sb_encap, NULL); - engine_add_input(&en_flow_output, &en_sb_multicast_group, NULL); + engine_add_input(&en_flow_output, &en_sb_multicast_group, flow_output_sb_multicast_group_handler); engine_add_input(&en_flow_output, &en_sb_datapath_binding, NULL); engine_add_input(&en_flow_output, &en_sb_port_binding, flow_output_sb_port_binding_handler); engine_add_input(&en_flow_output, &en_sb_mac_binding, NULL); diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c index d860686..de75f4a 100644 --- a/ovn/controller/physical.c +++ b/ovn/controller/physical.c @@ -937,6 +937,29 @@ physical_handle_port_binding_changes(struct ovn_desired_flow_table *flow_table, } void +physical_handle_mc_group_changes(struct ovn_desired_flow_table *flow_table, + struct controller_ctx *ctx, + enum mf_field_id mff_ovn_geneve, + const struct sbrec_chassis *chassis, + const struct simap *ct_zones, + struct hmap *local_datapaths) +{ + const struct sbrec_multicast_group *mc; + SBREC_MULTICAST_GROUP_FOR_EACH_TRACKED (mc, ctx->ovnsb_idl) { + if (sbrec_multicast_group_is_deleted(mc)) { + ofctrl_remove_flows(flow_table, &mc->header_.uuid); + } else { + if (!sbrec_multicast_group_is_new(mc)) { + ofctrl_remove_flows(flow_table, &mc->header_.uuid); + } + consider_mc_group(flow_table, mff_ovn_geneve, ct_zones, + local_datapaths, chassis, mc); + } + } +} + + +void physical_run(struct ovn_desired_flow_table *flow_table, struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, const struct ovsrec_bridge *br_int, diff --git a/ovn/controller/physical.h b/ovn/controller/physical.h index 88c5cda..eb3f8df 100644 --- a/ovn/controller/physical.h +++ b/ovn/controller/physical.h @@ -60,5 +60,10 @@ void physical_handle_port_binding_changes(struct ovn_desired_flow_table *, struct hmap *local_datapaths, struct chassis_index *, struct sset *active_tunnels); - +void physical_handle_mc_group_changes(struct ovn_desired_flow_table *, + struct controller_ctx *ctx, + enum mf_field_id mff_ovn_geneve, + const struct sbrec_chassis *, + const struct simap *ct_zones, + struct hmap *local_datapaths); #endif /* ovn/physical.h */ From patchwork Fri Jun 1 17:42:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 924268 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=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="K4LSlBGe"; dkim-atps=neutral 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 40yBdP579Nz9ry1 for ; Sat, 2 Jun 2018 03:48:25 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 1DBC0E5B; Fri, 1 Jun 2018 17:42:56 +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 303C5EED for ; Fri, 1 Jun 2018 17:42:50 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f68.google.com (mail-pl0-f68.google.com [209.85.160.68]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id A9688CF for ; Fri, 1 Jun 2018 17:42:49 +0000 (UTC) Received: by mail-pl0-f68.google.com with SMTP id u6-v6so15722379pls.9 for ; Fri, 01 Jun 2018 10:42:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=3HGSbWC/pWThQo9ZXRflrQIcFlXuovGXMWlzhfze/bQ=; b=K4LSlBGe3YJiK4wvccBFFd1YxlTPVeszSQs8MhO/0e6XvM7AkfhpL0BrbNuG/YMkrT JfrmQpHF4s+w4xdlSbFPz/UGlhxJvah3T9LkE8A2e6B/WXL82MNwL860LO2ICE/x2XiJ ZvtWefRfwBDn1fZ+7XH3u186OSyhu7eP8abBCCvzfxhLUGk/1P+EeUrB1nP6oSaMLHG+ Q3kTI5ziqwvNBqhw14Mjuiol3cI+B0W30MaZ7OI04o8sRIIcEkRRIcr6DpY2grVkwnCy D7FpW+xmtYoS7lH1Z/uslRfdBw33/vx+wVzf8SBMpI3ZBpV7/Q75kTTaFsF1XfBFf42U OKOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=3HGSbWC/pWThQo9ZXRflrQIcFlXuovGXMWlzhfze/bQ=; b=easrfIFZUanbQHppsMVCJyeW4OOVxIW7kDSLgXZq9lKCJJt5rs1t4pewR6yuwHuhVV jVPz2dFG7656q8IDDfuhzEo+aWSp5D9YPTRS+DAYVSJTLGFHtDKGnfCl0KhyjeJShgtE /rxt1bnTvrQ7Im7hYS2Dm200vjNK1EdXFAGnZFAa3v3cRT7n31m45cTGKS8aUI3QYnGs j2QucevllXB8FBYsMI+aubeJFVb6MRqimb9IbMklopBHqtyQEgU7A0782zgwvOHPynH4 qBoJDxJh8YVNqvdq/UGEbj9jeLztom8OyeOPy7zie3liaRajLxmP/rdnOBEXutNVKN7M eCTg== X-Gm-Message-State: ALKqPwe3qKlovBQeCUoXRYS7Tq4GM3o70SJWR75DPngG8G/Fn+x+fbEo FKjemcFtt9FegH4tkyfmjGjTRg== X-Google-Smtp-Source: ADUXVKICsSjpkndNsyfvjqIG4XLKb+iybUNEmyiiiRl2yDaZA5434A6NgdDdImEbzRZxjmoRDI/mzQ== X-Received: by 2002:a17:902:b60c:: with SMTP id b12-v6mr12350456pls.44.1527874969070; Fri, 01 Jun 2018 10:42:49 -0700 (PDT) Received: from localhost.localdomain.localdomain (c-73-162-150-77.hsd1.ca.comcast.net. [73.162.150.77]) by smtp.gmail.com with ESMTPSA id v26-v6sm9600279pfe.13.2018.06.01.10.42.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 Jun 2018 10:42:48 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Fri, 1 Jun 2018 10:42:01 -0700 Message-Id: <1527874926-40450-12-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> References: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v3 11/16] ovsdb-idl: Tracking - preserve data for deleted rows. 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 OVSDB IDL can track changes, but for deleted rows, the data is destroyed and only uuid is tracked. In some cases we need to check the data of the deleted rows. This patch preserves data for deleted rows until track clear is called. Signed-off-by: Han Zhou --- lib/ovsdb-idl-provider.h | 2 ++ lib/ovsdb-idl.c | 37 +++++++++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/lib/ovsdb-idl-provider.h b/lib/ovsdb-idl-provider.h index 70bfde1..745000d 100644 --- a/lib/ovsdb-idl-provider.h +++ b/lib/ovsdb-idl-provider.h @@ -73,6 +73,7 @@ struct ovsdb_idl_row { struct ovs_list dst_arcs; /* Backward arcs (ovsdb_idl_arc.dst_node). */ struct ovsdb_idl_table *table; /* Containing table. */ struct ovsdb_datum *old_datum; /* Committed data (null if orphaned). */ + bool parsed; /* Whether the row is parsed. */ /* Transactional data. */ struct ovsdb_datum *new_datum; /* Modified data (null to delete row). */ @@ -88,6 +89,7 @@ struct ovsdb_idl_row { unsigned int change_seqno[OVSDB_IDL_CHANGE_MAX]; struct ovs_list track_node; /* Rows modified/added/deleted by IDL */ unsigned long int *updated; /* Bitmap of columns updated by IDL */ + struct ovsdb_datum *tracked_old_datum; /* Old deleted data. */ }; struct ovsdb_idl_column { diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c index c6ff78e..1e7d121 100644 --- a/lib/ovsdb-idl.c +++ b/lib/ovsdb-idl.c @@ -1709,8 +1709,16 @@ ovsdb_idl_db_track_clear(struct ovsdb_idl_db *db) } ovs_list_remove(&row->track_node); ovs_list_init(&row->track_node); - if (ovsdb_idl_row_is_orphan(row)) { - ovsdb_idl_row_clear_old(row); + if (ovsdb_idl_row_is_orphan(row) && row->tracked_old_datum) { + ovsdb_idl_row_unparse(row); + const struct ovsdb_idl_table_class *class = + row->table->class_; + for (size_t c = 0; c < class->n_columns; c++) { + ovsdb_datum_destroy(&row->tracked_old_datum[c], + &class->columns[c].type); + } + free(row->tracked_old_datum); + row->tracked_old_datum = NULL; free(row); } } @@ -2437,10 +2445,14 @@ ovsdb_idl_row_parse(struct ovsdb_idl_row *row) const struct ovsdb_idl_table_class *class = row->table->class_; size_t i; + if (row->parsed) { + ovsdb_idl_row_unparse(row); + } for (i = 0; i < class->n_columns; i++) { const struct ovsdb_idl_column *c = &class->columns[i]; (c->parse)(row, &row->old_datum[i]); } + row->parsed = true; } static void @@ -2449,10 +2461,14 @@ ovsdb_idl_row_unparse(struct ovsdb_idl_row *row) const struct ovsdb_idl_table_class *class = row->table->class_; size_t i; + if (!row->parsed) { + return; + } for (i = 0; i < class->n_columns; i++) { const struct ovsdb_idl_column *c = &class->columns[i]; (c->unparse)(row); } + row->parsed = false; } /* The OVSDB-IDL Compound Indexes feature allows for the creation of custom @@ -2881,13 +2897,18 @@ ovsdb_idl_row_clear_old(struct ovsdb_idl_row *row) { ovs_assert(row->old_datum == row->new_datum); if (!ovsdb_idl_row_is_orphan(row)) { - const struct ovsdb_idl_table_class *class = row->table->class_; - size_t i; + if (ovsdb_idl_track_is_set(row->table)) { + row->tracked_old_datum = row->old_datum; + } else { + const struct ovsdb_idl_table_class *class = row->table->class_; + size_t i; - for (i = 0; i < class->n_columns; i++) { - ovsdb_datum_destroy(&row->old_datum[i], &class->columns[i].type); + for (i = 0; i < class->n_columns; i++) { + ovsdb_datum_destroy(&row->old_datum[i], + &class->columns[i].type); + } + free(row->old_datum); } - free(row->old_datum); row->old_datum = row->new_datum = NULL; } } @@ -3063,6 +3084,7 @@ ovsdb_idl_row_destroy_postprocess(struct ovsdb_idl_db *db) LIST_FOR_EACH_SAFE(row, next, track_node, &table->track_list) { if (!ovsdb_idl_track_is_set(row->table)) { ovs_list_remove(&row->track_node); + ovsdb_idl_row_unparse(row); free(row); } } @@ -3093,7 +3115,6 @@ static void ovsdb_idl_delete_row(struct ovsdb_idl_row *row) { ovsdb_idl_remove_from_indexes(row); - ovsdb_idl_row_unparse(row); ovsdb_idl_row_clear_arcs(row, true); ovsdb_idl_row_clear_old(row); if (ovs_list_is_empty(&row->dst_arcs)) { From patchwork Fri Jun 1 17:42:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 924270 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=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="sayS3rBA"; dkim-atps=neutral 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 40yBdy4Wzfz9ry1 for ; Sat, 2 Jun 2018 03:48:54 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 2BDD1F64; Fri, 1 Jun 2018 17:42:57 +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 2D1C5F51 for ; Fri, 1 Jun 2018 17:42:51 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pf0-f195.google.com (mail-pf0-f195.google.com [209.85.192.195]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 8124C136 for ; Fri, 1 Jun 2018 17:42:50 +0000 (UTC) Received: by mail-pf0-f195.google.com with SMTP id x9-v6so12840990pfm.2 for ; Fri, 01 Jun 2018 10:42:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=T/ClcTzH154+Y3+M/jExtFxlz15JISXyGRCAZvvDZc0=; b=sayS3rBAv2v3kwzdlHoC8VmH1VBivrwqnO++h66mj9MCRxPghQbshRTP6BWL/D01wK iiiALwJd7QDWblmt2zyxm37KmjBlBOQsu/jESsaQZWGCmtZw8a1hFaomR8f6Ljt2qPyl nl0fwQcclpXkaijloYcg+PSvL4wW+9MATNxs6aQT0XIVXnoH16z0WbAduGgGisM3bgGs ruL6CZ7d7CKQuMQ9GHOLPKJ8AfSJoNbnEQ9m0lCYWMmtap62s3TgZfuLzffG9/Re8tfV NQKFRF6DPUV7gcph2OnW9P/RCRbC9MvRts8k3M3bu1LMPw0ImWlww8bes6IJzs1Wlw8P XxnA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=T/ClcTzH154+Y3+M/jExtFxlz15JISXyGRCAZvvDZc0=; b=YSDJi5DhMBDBlFdKktxJadCnudqAu7MVoxdPKmOhVMiSJjAfZv5WE0WJ7Yep1GEXZ8 zYpNDPTtHIVRDukK9PDKDeFUEih4S4PqSIkR5hD9hgYUEEAUcQvEsI0yBnPIQcv3tvWs 23oQZVDjvaUzl9FqLtRKPDo0v0tVyrk5jCDRlrB0pXXy/QumKjBe4G/N2EbfMtdZBpKi 5kNF7QoxmKV2JCD5qlVQWJgcgnSdLKqLUl6EMw+eoyHyn+EJTpZdC2/JoOG3qhnp2fmP 8s/XelvXDcPiAUw+rnqAr05NYIqWT2fkXDp/7yJI3eZACjt78KW2CbZioVDjcKcPCGLl zWrA== X-Gm-Message-State: ALKqPwdP168F6hjIr9lDU5XmOrBLSNpH8TJ3RxTbs30Z7y8SULDLOy7R VEpwv4TpCFtKQRUnE+CP0BviPA== X-Google-Smtp-Source: ADUXVKJIePVyb8IWwufAJX83FyPudiE1Bj2niyC9Z0iI621H9Z/2+omv7skJpWwRdylSJwoVZutXAA== X-Received: by 2002:a62:121a:: with SMTP id a26-v6mr7760872pfj.104.1527874969924; Fri, 01 Jun 2018 10:42:49 -0700 (PDT) Received: from localhost.localdomain.localdomain (c-73-162-150-77.hsd1.ca.comcast.net. [73.162.150.77]) by smtp.gmail.com with ESMTPSA id v26-v6sm9600279pfe.13.2018.06.01.10.42.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 Jun 2018 10:42:49 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Fri, 1 Jun 2018 10:42:02 -0700 Message-Id: <1527874926-40450-13-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> References: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v3 12/16] ovn-controller: Split addr_sets from runtime_data. 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: Han Zhou --- ovn/controller/ovn-controller.c | 94 ++++++++++++++++++++++++++++++++++------- 1 file changed, 78 insertions(+), 16 deletions(-) diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 56902ff..8b0cd46 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -291,13 +291,24 @@ get_chassis_id(const struct ovsdb_idl *ovs_idl) /* Iterate address sets in the southbound database. Create and update the * corresponding symtab entries as necessary. */ static void -addr_sets_init(struct controller_ctx *ctx, struct shash *addr_sets) +addr_sets_update(struct controller_ctx *ctx, struct shash *addr_sets, + struct sset *new, struct sset *deleted, struct sset *updated) { const struct sbrec_address_set *as; - SBREC_ADDRESS_SET_FOR_EACH (as, ctx->ovnsb_idl) { - expr_const_sets_add(addr_sets, as->name, - (const char *const *) as->addresses, - as->n_addresses, true); + SBREC_ADDRESS_SET_FOR_EACH_TRACKED (as, ctx->ovnsb_idl) { + if (sbrec_address_set_is_deleted(as)) { + expr_const_sets_remove(addr_sets, as->name); + sset_add(deleted, as->name); + } else { + expr_const_sets_add(addr_sets, as->name, + (const char *const *) as->addresses, + as->n_addresses, true); + if (sbrec_address_set_is_new(as)) { + sset_add(new, as->name); + } else { + sset_add(updated, as->name); + } + } } } @@ -606,6 +617,53 @@ ENGINE_FUNC_SB(gateway_chassis); ENGINE_FUNC_OVS(port); ENGINE_FUNC_OVS(interface); +struct ed_type_addr_sets { + struct shash addr_sets; + struct sset new; + struct sset deleted; + struct sset updated; +}; + +static void +en_addr_sets_init(struct engine_node *node) +{ + struct ed_type_addr_sets *as = (struct ed_type_addr_sets *)node->data; + shash_init(&as->addr_sets); + sset_init(&as->new); + sset_init(&as->deleted); + sset_init(&as->updated); +} + +static void +en_addr_sets_cleanup(struct engine_node *node) +{ + struct ed_type_addr_sets *as = (struct ed_type_addr_sets *)node->data; + expr_const_sets_destroy(&as->addr_sets); + shash_destroy(&as->addr_sets); + sset_destroy(&as->new); + sset_destroy(&as->deleted); + sset_destroy(&as->updated); +} + +/* For en_addr_sets, the run function handles changes since there is only + * one input */ +static void +en_addr_sets_run(struct engine_node *node) +{ + struct controller_ctx *ctx = (struct controller_ctx *)node->context; + struct ed_type_addr_sets *as = (struct ed_type_addr_sets *)node->data; + + sset_clear(&as->new); + sset_clear(&as->deleted); + sset_clear(&as->updated); + + addr_sets_update(ctx, &as->addr_sets, &as->new, + &as->deleted, &as->updated); + + node->changed = !sset_is_empty(&as->new) || !sset_is_empty(&as->deleted) + || !sset_is_empty(&as->updated); +} + struct ed_type_runtime_data { struct chassis_index chassis_index; @@ -623,7 +681,6 @@ struct ed_type_runtime_data { * _ */ struct sset local_lport_ids; struct sset active_tunnels; - struct shash addr_sets; struct shash port_groups; /* connection tracking zones. */ @@ -642,7 +699,6 @@ en_runtime_data_init(struct engine_node *node) sset_init(&data->local_lports); sset_init(&data->local_lport_ids); sset_init(&data->active_tunnels); - shash_init(&data->addr_sets); shash_init(&data->port_groups); shash_init(&data->pending_ct_zones); simap_init(&data->ct_zones); @@ -659,8 +715,6 @@ en_runtime_data_cleanup(struct engine_node *node) struct ed_type_runtime_data *data = (struct ed_type_runtime_data *)node->data; - expr_const_sets_destroy(&data->addr_sets); - shash_destroy(&data->addr_sets); expr_const_sets_destroy(&data->port_groups); shash_destroy(&data->port_groups); @@ -693,7 +747,6 @@ en_runtime_data_run(struct engine_node *node) struct sset *local_lport_ids = &data->local_lport_ids; struct sset *active_tunnels = &data->active_tunnels; struct chassis_index *chassis_index = &data->chassis_index; - struct shash *addr_sets = &data->addr_sets; struct shash *port_groups = &data->port_groups; unsigned long *ct_zone_bitmap = data->ct_zone_bitmap; struct shash *pending_ct_zones = &data->pending_ct_zones; @@ -715,7 +768,6 @@ en_runtime_data_run(struct engine_node *node) sset_destroy(local_lport_ids); sset_destroy(active_tunnels); chassis_index_destroy(chassis_index); - expr_const_sets_destroy(addr_sets); expr_const_sets_destroy(port_groups); sset_init(local_lports); sset_init(local_lport_ids); @@ -737,7 +789,6 @@ en_runtime_data_run(struct engine_node *node) chassis_index, active_tunnels, local_datapaths, local_lports, local_lport_ids); - addr_sets_init(ctx, addr_sets); port_groups_init(ctx, port_groups); update_ct_zones(local_lports, local_datapaths, ct_zones, ct_zone_bitmap, pending_ct_zones); @@ -815,10 +866,13 @@ en_flow_output_run(struct engine_node *node) struct sset *local_lport_ids = &rt_data->local_lport_ids; struct sset *active_tunnels = &rt_data->active_tunnels; struct chassis_index *chassis_index = &rt_data->chassis_index; - struct shash *addr_sets = &rt_data->addr_sets; struct shash *port_groups = &rt_data->port_groups; struct simap *ct_zones = &rt_data->ct_zones; + struct ed_type_addr_sets *as_data = + (struct ed_type_addr_sets *)engine_get_input("addr_sets", node)->data; + struct shash *addr_sets = &as_data->addr_sets; + const struct ovsrec_bridge *br_int = get_br_int(ctx); const char *chassis_id = get_chassis_id(ctx->ovs_idl); @@ -873,8 +927,11 @@ flow_output_sb_logical_flow_handler(struct engine_node *node) struct sset *local_lport_ids = &data->local_lport_ids; struct sset *active_tunnels = &data->active_tunnels; struct chassis_index *chassis_index = &data->chassis_index; - struct shash *addr_sets = &data->addr_sets; struct shash *port_groups = &data->port_groups; + struct ed_type_addr_sets *as_data = + (struct ed_type_addr_sets *)engine_get_input("addr_sets", node)->data; + struct shash *addr_sets = &as_data->addr_sets; + const struct ovsrec_bridge *br_int = get_br_int(ctx); const char *chassis_id = get_chassis_id(ctx->ovs_idl); @@ -1068,6 +1125,7 @@ main(int argc, char *argv[]) }; struct ed_type_runtime_data ed_runtime_data; struct ed_type_flow_output ed_flow_output; + struct ed_type_addr_sets ed_addr_sets; ENGINE_NODE_SB(chassis, "chassis", &ctx); ENGINE_NODE_SB(encap, "encap", &ctx); @@ -1086,8 +1144,13 @@ main(int argc, char *argv[]) ENGINE_NODE_OVS(port, "ovs_table_port", &ctx); ENGINE_NODE_OVS(interface, "ovs_table_interface", &ctx); + ENGINE_NODE(addr_sets, "addr_sets", &ctx); ENGINE_NODE(runtime_data, "runtime_data", &ctx); ENGINE_NODE(flow_output, "flow_output", &ctx); + + engine_add_input(&en_addr_sets, &en_sb_address_set, NULL); + + engine_add_input(&en_flow_output, &en_addr_sets, NULL); engine_add_input(&en_flow_output, &en_runtime_data, NULL); engine_add_input(&en_flow_output, &en_ovs_port, NULL); @@ -1109,7 +1172,6 @@ main(int argc, char *argv[]) engine_add_input(&en_runtime_data, &en_ovs_interface, NULL); engine_add_input(&en_runtime_data, &en_sb_chassis, NULL); - engine_add_input(&en_runtime_data, &en_sb_address_set, NULL); engine_add_input(&en_runtime_data, &en_sb_port_group, NULL); engine_add_input(&en_runtime_data, &en_sb_datapath_binding, NULL); engine_add_input(&en_runtime_data, &en_sb_port_binding, runtime_data_sb_port_binding_handler); @@ -1217,7 +1279,7 @@ main(int argc, char *argv[]) if (br_int && chassis) { char *error = ofctrl_inject_pkt(br_int, pending_pkt.flow_s, &ed_runtime_data.port_groups, - &ed_runtime_data.addr_sets); + &ed_addr_sets.addr_sets); if (error) { unixctl_command_reply_error(pending_pkt.conn, error); free(error); From patchwork Fri Jun 1 17:42:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 924271 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=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="cyKc2KF7"; dkim-atps=neutral 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 40yBfm32dwz9ry1 for ; Sat, 2 Jun 2018 03:49:36 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 1DF87F7A; Fri, 1 Jun 2018 17:42:59 +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 143C7F53 for ; Fri, 1 Jun 2018 17:42:53 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f65.google.com (mail-pl0-f65.google.com [209.85.160.65]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id B94C46DB for ; Fri, 1 Jun 2018 17:42:51 +0000 (UTC) Received: by mail-pl0-f65.google.com with SMTP id az12-v6so15720724plb.8 for ; Fri, 01 Jun 2018 10:42:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=AF+bnNEKu5SKKT3UnnlMWA9pbDyw/EWt4nnEOw5TPpU=; b=cyKc2KF7OaC7Vp5kqQo/8A3WB1h0iWI9nLfdW89YkOEWUY6UhtAOUB10SsRq3LfWNz M2XUJoevj1Vf8QO/cAhSGkVFCUrgSi2tRlO9eeas5ny4DhmYYdEJB8OO/wFGO0r7MknB bAJGnDFdiDGymzI06AC5EIr9QWv16+SVxOUblbQ5VVSnRV52LyhKMBAVWPcewLQhYFqe 6a31W7IyWmbde5xEPB+5xJT1w7187EX6vNCpCIg+jeTbq8BjuDK+vU0lkU7g7VMUQeNu UO79l8RbS98IrcRY6ni7xUxCr7CM7ymAl3l75vXkIizkhAts1ORdJkv/NkLNRBnYTyTu tVjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=AF+bnNEKu5SKKT3UnnlMWA9pbDyw/EWt4nnEOw5TPpU=; b=gtKVnUQOXyz7sWjsX1vBox/ILn3CG1oaPnTFVAHRCjqv40WeqWeQ86uWHUxrHZndiU 2JmilYZ5j+L7b+qrDECR3UaoQKkKvB6MPxzMEz6h31MnllEYfCumcZP49S2v4AJjhfFI YKhKa/0Y9ReetwTBdsVogyPCnbcWVmCuZBbgHjxsaIXUKfqNy0OuDZn6NBTmN08y2219 ZPkXNpsrBH/qmQpHBAiBf3jE8v9+/e4Q9jxuotBLu9UEQ2yU71+S/ObNjSmUuOcX6m6+ zghsv24TwRaK926TcfGsha5+VM0qDYSLBlS2w04AIUWo4Xg73zdyhLiBnKzg3AO5YvLQ dduA== X-Gm-Message-State: ALKqPwcGEB50+j5V0hAbv//2Jtvw8olpskstmvRyiIa6UvVt/fG4yEp1 1cKnXwGNOWYFpfvj4lLlw2v/hQ== X-Google-Smtp-Source: ADUXVKIWRbqtK7gNqaxB/2Y5FMPlX8/y5B3BaUnNKbu4etc75q4UJn3+1buuobaGK6zzIFwhU92Xsw== X-Received: by 2002:a17:902:8b85:: with SMTP id ay5-v6mr11671229plb.30.1527874970834; Fri, 01 Jun 2018 10:42:50 -0700 (PDT) Received: from localhost.localdomain.localdomain (c-73-162-150-77.hsd1.ca.comcast.net. [73.162.150.77]) by smtp.gmail.com with ESMTPSA id v26-v6sm9600279pfe.13.2018.06.01.10.42.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 Jun 2018 10:42:50 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Fri, 1 Jun 2018 10:42:03 -0700 Message-Id: <1527874926-40450-14-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> References: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v3 13/16] ovn-controller: Maintain resource references for logical flows. 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 This patch maintains the cross reference between logical flows and the resources such as address sets and port groups that are used by logical flows. This data will be needed in address set and port group incremental processing. Signed-off-by: Han Zhou --- include/ovn/expr.h | 5 +- ovn/controller/lflow.c | 147 ++++++++++++++++++++++++++++++++++++++-- ovn/controller/lflow.h | 52 ++++++++++++++ ovn/controller/ovn-controller.c | 14 ++-- ovn/lib/actions.c | 2 +- ovn/lib/expr.c | 21 ++++-- ovn/utilities/ovn-trace.c | 2 +- tests/test-ovn.c | 7 +- 8 files changed, 230 insertions(+), 20 deletions(-) diff --git a/include/ovn/expr.h b/include/ovn/expr.h index 3995e62..c0664ac 100644 --- a/include/ovn/expr.h +++ b/include/ovn/expr.h @@ -65,6 +65,7 @@ struct flow; struct ofpbuf; struct shash; struct simap; +struct sset; /* "Measurement level" of a field. See "Level of Measurement" in the large * comment on struct expr_symbol below for more information. */ @@ -383,10 +384,12 @@ void expr_format(const struct expr *, struct ds *); void expr_print(const struct expr *); struct expr *expr_parse(struct lexer *, const struct shash *symtab, const struct shash *addr_sets, - const struct shash *port_groups); + const struct shash *port_groups, + struct sset *addr_sets_ref); struct expr *expr_parse_string(const char *, const struct shash *symtab, const struct shash *addr_sets, const struct shash *port_groups, + struct sset *addr_sets_ref, char **errorp); struct expr *expr_clone(struct expr *); diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c index 9d8f693..a39e241 100644 --- a/ovn/controller/lflow.c +++ b/ovn/controller/lflow.c @@ -62,6 +62,7 @@ struct condition_aux { }; static bool consider_logical_flow(struct ovn_desired_flow_table *flow_table, + struct lflow_resource_ref *lfrr, struct controller_ctx *ctx, const struct chassis_index *chassis_index, const struct sbrec_logical_flow *lflow, @@ -135,9 +136,132 @@ is_switch(const struct sbrec_datapath_binding *ldp) } +void +lflow_resource_init(struct lflow_resource_ref *lfrr) +{ + hmap_init(&lfrr->ref_lflow_table); + hmap_init(&lfrr->lflow_ref_table); +} + +void +lflow_resource_destroy(struct lflow_resource_ref *lfrr) +{ + struct ref_lflow_node *rlfn, *rlfn_next; + HMAP_FOR_EACH_SAFE (rlfn, rlfn_next, node, &lfrr->ref_lflow_table) { + free(rlfn->ref_name); + struct lflow_ref_list_node *lrln, *next; + LIST_FOR_EACH_SAFE (lrln, next, ref_list, &rlfn->ref_lflow_head) { + ovs_list_remove(&lrln->ref_list); + ovs_list_remove(&lrln->lflow_list); + free(lrln); + } + hmap_remove(&lfrr->ref_lflow_table, &rlfn->node); + free(rlfn); + } + hmap_destroy(&lfrr->ref_lflow_table); + + struct lflow_ref_node *lfrn, *lfrn_next; + HMAP_FOR_EACH_SAFE (lfrn, lfrn_next, node, &lfrr->lflow_ref_table) { + hmap_remove(&lfrr->lflow_ref_table, &lfrn->node); + free(lfrn); + } + hmap_destroy(&lfrr->lflow_ref_table); +} + +void +lflow_resource_clear(struct lflow_resource_ref *lfrr) +{ + lflow_resource_destroy(lfrr); + lflow_resource_init(lfrr); +} + +static struct ref_lflow_node* +ref_lflow_lookup(struct hmap *ref_lflow_table, + enum ref_type type, const char *ref_name) +{ + struct ref_lflow_node *rlfn; + + HMAP_FOR_EACH_WITH_HASH (rlfn, node, hash_string(ref_name, type), + ref_lflow_table) { + if (rlfn->type == type && !strcmp(rlfn->ref_name, ref_name)) { + return rlfn; + } + } + return NULL; +} + +static struct lflow_ref_node* +lflow_ref_lookup(struct hmap *lflow_ref_table, + const struct uuid *lflow_uuid) +{ + struct lflow_ref_node *lfrn; + + HMAP_FOR_EACH_WITH_HASH (lfrn, node, uuid_hash(lflow_uuid), + lflow_ref_table) { + if (uuid_equals(&lfrn->lflow_uuid, lflow_uuid)) { + return lfrn; + } + } + return NULL; +} + +static void +lflow_resource_add(struct lflow_resource_ref *lfrr, enum ref_type type, + const char *ref_name, const struct uuid *lflow_uuid) +{ + struct ref_lflow_node *rlfn = ref_lflow_lookup(&lfrr->ref_lflow_table, + type, ref_name); + if (!rlfn) { + rlfn = xzalloc(sizeof *rlfn); + rlfn->node.hash = hash_string(ref_name, type); + rlfn->type = type; + rlfn->ref_name = xstrdup(ref_name); + ovs_list_init(&rlfn->ref_lflow_head); + hmap_insert(&lfrr->ref_lflow_table, &rlfn->node, rlfn->node.hash); + } + + struct lflow_ref_node *lfrn = lflow_ref_lookup(&lfrr->lflow_ref_table, + lflow_uuid); + if (!lfrn) { + lfrn = xzalloc(sizeof *lfrn); + lfrn->node.hash = uuid_hash(lflow_uuid); + lfrn->lflow_uuid = *lflow_uuid; + ovs_list_init(&lfrn->lflow_ref_head); + hmap_insert(&lfrr->lflow_ref_table, &lfrn->node, lfrn->node.hash); + } + + struct lflow_ref_list_node *lrln = xzalloc(sizeof *lrln); + lrln->type = type; + lrln->ref_name = xstrdup(ref_name); + lrln->lflow_uuid = *lflow_uuid; + ovs_list_push_back(&rlfn->ref_lflow_head, &lrln->ref_list); + ovs_list_push_back(&lfrn->lflow_ref_head, &lrln->lflow_list); +} + +static void +lflow_resource_destroy_lflow(struct lflow_resource_ref *lfrr, + const struct uuid *lflow_uuid) +{ + struct lflow_ref_node *lfrn = lflow_ref_lookup(&lfrr->lflow_ref_table, + lflow_uuid); + if (!lfrn) { + return; + } + + hmap_remove(&lfrr->lflow_ref_table, &lfrn->node); + struct lflow_ref_list_node *lrln, *next; + LIST_FOR_EACH_SAFE (lrln, next, lflow_list, &lfrn->lflow_ref_head) { + ovs_list_remove(&lrln->ref_list); + ovs_list_remove(&lrln->lflow_list); + free(lrln); + } + free(lfrn); +} + /* Adds the logical flows from the Logical_Flow table to flow tables. */ static void add_logical_flows(struct ovn_desired_flow_table *flow_table, + struct lflow_resource_ref *lfrr, struct controller_ctx *ctx, const struct chassis_index *chassis_index, const struct hmap *local_datapaths, @@ -171,7 +295,7 @@ add_logical_flows(struct ovn_desired_flow_table *flow_table, nd_ra_opts_init(&nd_ra_opts); SBREC_LOGICAL_FLOW_FOR_EACH (lflow, ctx->ovnsb_idl) { - if (!consider_logical_flow(flow_table, ctx, chassis_index, + if (!consider_logical_flow(flow_table, lfrr, ctx, chassis_index, lflow, local_datapaths, group_table, meter_table, chassis, &dhcp_opts, &dhcpv6_opts, &nd_ra_opts, @@ -190,6 +314,7 @@ add_logical_flows(struct ovn_desired_flow_table *flow_table, bool lflow_handle_changed_flows(struct ovn_desired_flow_table *flow_table, + struct lflow_resource_ref *lfrr, struct controller_ctx *ctx, const struct sbrec_chassis *chassis, const struct chassis_index *chassis_index, @@ -232,6 +357,8 @@ lflow_handle_changed_flows(struct ovn_desired_flow_table *flow_table, VLOG_DBG("handle deleted lflow "UUID_FMT, UUID_ARGS(&lflow->header_.uuid)); ofctrl_remove_flows(flow_table, &lflow->header_.uuid); + /* Delete entries from lflow resource reference. */ + lflow_resource_destroy_lflow(lfrr, &lflow->header_.uuid); } } SBREC_LOGICAL_FLOW_FOR_EACH_TRACKED (lflow, ctx->ovnsb_idl) { @@ -243,10 +370,12 @@ lflow_handle_changed_flows(struct ovn_desired_flow_table *flow_table, VLOG_DBG("handle updated lflow "UUID_FMT, UUID_ARGS(&lflow->header_.uuid)); ofctrl_remove_flows(flow_table, &lflow->header_.uuid); + /* Delete entries from lflow resource reference. */ + lflow_resource_destroy_lflow(lfrr, &lflow->header_.uuid); } VLOG_DBG("handle new lflow "UUID_FMT, UUID_ARGS(&lflow->header_.uuid)); - if (!consider_logical_flow(flow_table, ctx, chassis_index, + if (!consider_logical_flow(flow_table, lfrr, ctx, chassis_index, lflow, local_datapaths, group_table, meter_table, chassis, &dhcp_opts, &dhcpv6_opts, &nd_ra_opts, @@ -276,6 +405,7 @@ update_conj_id_ofs(uint32_t *conj_id_ofs, uint32_t n_conjs) static bool consider_logical_flow(struct ovn_desired_flow_table *flow_table, + struct lflow_resource_ref *lfrr, struct controller_ctx *ctx, const struct chassis_index *chassis_index, const struct sbrec_logical_flow *lflow, @@ -349,8 +479,16 @@ consider_logical_flow(struct ovn_desired_flow_table *flow_table, struct hmap matches; struct expr *expr; + struct sset addr_sets_ref = SSET_INITIALIZER(&addr_sets_ref); expr = expr_parse_string(lflow->match, &symtab, addr_sets, port_groups, - &error); + &addr_sets_ref, &error); + const char *addr_set_name; + SSET_FOR_EACH (addr_set_name, &addr_sets_ref) { + lflow_resource_add(lfrr, REF_TYPE_ADDRSET, addr_set_name, + &lflow->header_.uuid); + } + sset_destroy(&addr_sets_ref); + if (!error) { if (prereqs) { expr = expr_combine(EXPR_T_AND, expr, prereqs); @@ -544,6 +682,7 @@ add_neighbor_flows(struct ovn_desired_flow_table *flow_table, * into OpenFlow flows. See ovn-architecture(7) for more information. */ void lflow_run(struct ovn_desired_flow_table *flow_table, + struct lflow_resource_ref *lfrr, struct controller_ctx *ctx, const struct sbrec_chassis *chassis, const struct chassis_index *chassis_index, @@ -558,7 +697,7 @@ lflow_run(struct ovn_desired_flow_table *flow_table, { COVERAGE_INC(lflow_run); - add_logical_flows(flow_table, ctx, chassis_index, local_datapaths, + add_logical_flows(flow_table, lfrr, ctx, chassis_index, local_datapaths, group_table, meter_table, chassis, addr_sets, port_groups, active_tunnels, local_lport_ids, conj_id_ofs); diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h index d407c2c..bc6c7ac 100644 --- a/ovn/controller/lflow.h +++ b/ovn/controller/lflow.h @@ -34,12 +34,16 @@ */ #include +#include "openvswitch/hmap.h" +#include "openvswitch/uuid.h" +#include "openvswitch/list.h" struct chassis_index; struct controller_ctx; struct ovn_extend_table; struct ovn_desired_flow_table; struct hmap; +struct hmap_node; struct sbrec_chassis; struct simap; struct sset; @@ -62,8 +66,55 @@ struct uuid; /* The number of tables for the ingress and egress pipelines. */ #define LOG_PIPELINE_LEN 24 +enum ref_type { + REF_TYPE_ADDRSET +}; + +/* Maintains the relationship for a pair of named resource and + * a lflow, indexed by both ref_lflow_table and lflow_ref_table. */ +struct lflow_ref_list_node { + struct ovs_list lflow_list; /* list for same lflow */ + struct ovs_list ref_list; /* list for same ref */ + enum ref_type type; + char *ref_name; + struct uuid lflow_uuid; +}; + +struct ref_lflow_node { + struct hmap_node node; + enum ref_type type; /* key */ + char *ref_name; /* key */ + struct ovs_list ref_lflow_head; +}; + +struct lflow_ref_node { + struct hmap_node node; + struct uuid lflow_uuid; /* key */ + struct ovs_list lflow_ref_head; +}; + +struct lflow_resource_ref { + /* A map from a referenced resource type & name (e.g. address_set AS1) + * to a list of lflows that are referencing the named resource. Data + * type of each node in this hmap is struct ref_lflow_node. The + * ref_lflow_head in each node points to a list of + * lflow_ref_list_node.ref_list. */ + struct hmap ref_lflow_table; + + /* A map from a lflow uuid to a list of named resources that are + * referenced by the lflow. Data type of each node in this hmap is + * struct lflow_ref_node. The lflow_ref_head in each node points to + * a list of lflow_ref_list_node.lflow_list. */ + struct hmap lflow_ref_table; +}; + +void lflow_resource_init(struct lflow_resource_ref *); +void lflow_resource_destroy(struct lflow_resource_ref *); +void lflow_resource_clear(struct lflow_resource_ref *); + void lflow_init(void); void lflow_run(struct ovn_desired_flow_table *, + struct lflow_resource_ref *, struct controller_ctx *, const struct sbrec_chassis *chassis, const struct chassis_index *, @@ -76,6 +127,7 @@ void lflow_run(struct ovn_desired_flow_table *, struct sset *local_lport_ids, uint32_t *conj_id_ofs); bool lflow_handle_changed_flows(struct ovn_desired_flow_table *, + struct lflow_resource_ref *, struct controller_ctx *ctx, const struct sbrec_chassis *chassis, const struct chassis_index *chassis_index, diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 8b0cd46..7d0bde5 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -831,6 +831,8 @@ struct ed_type_flow_output { struct ovn_extend_table meter_table; /* conjunction id offset */ uint32_t conj_id_ofs; + /* lflow resource cross reference */ + struct lflow_resource_ref lflow_resource_ref; }; static void @@ -842,6 +844,7 @@ en_flow_output_init(struct engine_node *node) ovn_extend_table_init(&data->group_table); ovn_extend_table_init(&data->meter_table); data->conj_id_ofs = 1; + lflow_resource_init(&data->lflow_resource_ref); } static void @@ -852,6 +855,7 @@ en_flow_output_cleanup(struct engine_node *node) ovn_desired_flow_table_destroy(&data->flow_table); ovn_extend_table_destroy(&data->group_table); ovn_extend_table_destroy(&data->meter_table); + lflow_resource_destroy(&data->lflow_resource_ref); } static void @@ -890,6 +894,7 @@ en_flow_output_run(struct engine_node *node) struct ovn_extend_table *group_table = &fo->group_table; struct ovn_extend_table *meter_table = &fo->meter_table; uint32_t *conj_id_ofs = &fo->conj_id_ofs; + struct lflow_resource_ref *lfrr = &fo->lflow_resource_ref; static bool first_run = true; if (first_run) { @@ -898,12 +903,12 @@ en_flow_output_run(struct engine_node *node) ovn_desired_flow_table_clear(flow_table); ovn_extend_table_clear(group_table, false /* desired */); ovn_extend_table_clear(meter_table, false /* desired */); + lflow_resource_clear(lfrr); } *conj_id_ofs = 1; - lflow_run(flow_table, ctx, chassis, - chassis_index, local_datapaths, group_table, - meter_table, addr_sets, port_groups, active_tunnels, + lflow_run(flow_table, lfrr, ctx, chassis, chassis_index, local_datapaths, + group_table, meter_table, addr_sets, port_groups, active_tunnels, local_lport_ids, conj_id_ofs); enum mf_field_id mff_ovn_geneve = ofctrl_get_mf_field_id(); @@ -950,8 +955,9 @@ flow_output_sb_logical_flow_handler(struct engine_node *node) struct ovn_extend_table *group_table = &fo->group_table; struct ovn_extend_table *meter_table = &fo->meter_table; uint32_t *conj_id_ofs = &fo->conj_id_ofs; + struct lflow_resource_ref *lfrr = &fo->lflow_resource_ref; - bool handled = lflow_handle_changed_flows(flow_table, ctx, chassis, + bool handled = lflow_handle_changed_flows(flow_table, lfrr, ctx, chassis, chassis_index, local_datapaths, group_table, meter_table, addr_sets, port_groups, active_tunnels, local_lport_ids, conj_id_ofs); diff --git a/ovn/lib/actions.c b/ovn/lib/actions.c index 20c8267..1cb9bed 100644 --- a/ovn/lib/actions.c +++ b/ovn/lib/actions.c @@ -234,7 +234,7 @@ add_prerequisite(struct action_context *ctx, const char *prerequisite) struct expr *expr; char *error; - expr = expr_parse_string(prerequisite, ctx->pp->symtab, NULL, NULL, + expr = expr_parse_string(prerequisite, ctx->pp->symtab, NULL, NULL, NULL, &error); ovs_assert(!error); ctx->prereqs = expr_combine(EXPR_T_AND, ctx->prereqs, expr); diff --git a/ovn/lib/expr.c b/ovn/lib/expr.c index 148ac86..13c81c8 100644 --- a/ovn/lib/expr.c +++ b/ovn/lib/expr.c @@ -465,6 +465,7 @@ struct expr_context { const struct shash *symtab; /* Symbol table. */ const struct shash *addr_sets; /* Address set table. */ const struct shash *port_groups; /* Port group table. */ + struct sset *addr_sets_ref; /* The set of address set referenced. */ bool not; /* True inside odd number of NOT operators. */ }; @@ -727,6 +728,10 @@ static bool parse_addr_sets(struct expr_context *ctx, struct expr_constant_set *cs, size_t *allocated_values) { + if (ctx->addr_sets_ref) { + sset_add(ctx->addr_sets_ref, ctx->lexer->token.s); + } + struct expr_constant_set *addr_sets = (ctx->addr_sets ? shash_find_data(ctx->addr_sets, ctx->lexer->token.s) @@ -1261,12 +1266,14 @@ expr_parse__(struct expr_context *ctx) struct expr * expr_parse(struct lexer *lexer, const struct shash *symtab, const struct shash *addr_sets, - const struct shash *port_groups) + const struct shash *port_groups, + struct sset *addr_sets_ref) { struct expr_context ctx = { .lexer = lexer, .symtab = symtab, .addr_sets = addr_sets, - .port_groups = port_groups }; + .port_groups = port_groups, + .addr_sets_ref = addr_sets_ref }; return lexer->error ? NULL : expr_parse__(&ctx); } @@ -1280,13 +1287,15 @@ struct expr * expr_parse_string(const char *s, const struct shash *symtab, const struct shash *addr_sets, const struct shash *port_groups, + struct sset *addr_sets_ref, char **errorp) { struct lexer lexer; lexer_init(&lexer, s); lexer_get(&lexer); - struct expr *expr = expr_parse(&lexer, symtab, addr_sets, port_groups); + struct expr *expr = expr_parse(&lexer, symtab, addr_sets, port_groups, + addr_sets_ref); lexer_force_end(&lexer); *errorp = lexer_steal_error(&lexer); if (*errorp) { @@ -1510,7 +1519,7 @@ expr_get_level(const struct expr *expr) static enum expr_level expr_parse_level(const char *s, const struct shash *symtab, char **errorp) { - struct expr *expr = expr_parse_string(s, symtab, NULL, NULL, errorp); + struct expr *expr = expr_parse_string(s, symtab, NULL, NULL, NULL, errorp); enum expr_level level = expr ? expr_get_level(expr) : EXPR_L_NOMINAL; expr_destroy(expr); return level; @@ -1668,7 +1677,7 @@ parse_and_annotate(const char *s, const struct shash *symtab, char *error; struct expr *expr; - expr = expr_parse_string(s, symtab, NULL, NULL, &error); + expr = expr_parse_string(s, symtab, NULL, NULL, NULL, &error); if (expr) { expr = expr_annotate_(expr, symtab, nesting, &error); } @@ -3392,7 +3401,7 @@ expr_parse_microflow(const char *s, const struct shash *symtab, lexer_init(&lexer, s); lexer_get(&lexer); - struct expr *e = expr_parse(&lexer, symtab, addr_sets, port_groups); + struct expr *e = expr_parse(&lexer, symtab, addr_sets, port_groups, NULL); lexer_force_end(&lexer); if (e) { diff --git a/ovn/utilities/ovn-trace.c b/ovn/utilities/ovn-trace.c index 1fd48f2..39fa14c 100644 --- a/ovn/utilities/ovn-trace.c +++ b/ovn/utilities/ovn-trace.c @@ -813,7 +813,7 @@ read_flows(void) char *error; struct expr *match; match = expr_parse_string(sblf->match, &symtab, &address_sets, - &port_groups, &error); + &port_groups, NULL, &error); if (error) { VLOG_WARN("%s: parsing expression failed (%s)", sblf->match, error); diff --git a/tests/test-ovn.c b/tests/test-ovn.c index d4a5d59..ce4e8e3 100644 --- a/tests/test-ovn.c +++ b/tests/test-ovn.c @@ -281,7 +281,7 @@ test_parse_expr__(int steps) char *error; expr = expr_parse_string(ds_cstr(&input), &symtab, &addr_sets, - &port_groups, &error); + &port_groups, NULL, &error); if (!error && steps > 0) { expr = expr_annotate(expr, &symtab, &error); } @@ -405,7 +405,8 @@ test_evaluate_expr(struct ovs_cmdl_context *ctx) while (!ds_get_test_line(&input, stdin)) { struct expr *expr; - expr = expr_parse_string(ds_cstr(&input), &symtab, NULL, NULL, &error); + expr = expr_parse_string(ds_cstr(&input), &symtab, NULL, NULL, NULL, + &error); if (!error) { expr = expr_annotate(expr, &symtab, &error); } @@ -880,7 +881,7 @@ test_tree_shape_exhaustively(struct expr *expr, struct shash *symtab, char *error; modified = expr_parse_string(ds_cstr(&s), symtab, NULL, - NULL, &error); + NULL, NULL, &error); if (error) { fprintf(stderr, "%s fails to parse (%s)\n", ds_cstr(&s), error); From patchwork Fri Jun 1 17:42:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 924272 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=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="OrZVQPPZ"; dkim-atps=neutral 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 40yBgD3j2Qz9ry1 for ; Sat, 2 Jun 2018 03:50:00 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 3FD2CF7E; Fri, 1 Jun 2018 17:43:00 +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 6EAB2F19 for ; Fri, 1 Jun 2018 17:42:53 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f42.google.com (mail-pl0-f42.google.com [209.85.160.42]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 943E5CF for ; Fri, 1 Jun 2018 17:42:52 +0000 (UTC) Received: by mail-pl0-f42.google.com with SMTP id v24-v6so15722858plo.3 for ; Fri, 01 Jun 2018 10:42:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=piCuT+zuzJJscHwCfjYPqMS4WmYMmskFdvn0FFcaPes=; b=OrZVQPPZyEONgNZiczeitPWC9xEWxGqkcaghUEdhWrJWSTb0MMb+VkE/QMYHScgYJZ pt8AiRCvmaQUHvQ0nTWvzxp0tn49LOYs1hCOJLwwiZe9Sw9sJzJFQe0amxMHij1kwU7N jUXGNXzKRSHLmTPfBPi2GdOTd+UFAUB5AOOcqvrm71dNKQruTWysRym8Ej+wcuV8SvQO rRerkqvsxLQnCvbhJn48wsVUgtGNRR0Phb/6Q+kEmkTcrWem7Af3gZtq9nTTO+9qEGGc RGcI3JOQL2noXVQmQxJkigSOCC/VHMRrRfuf7NM4pwwA08Y+kB+Kv1PSC+QYp/T5hLji a/UA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=piCuT+zuzJJscHwCfjYPqMS4WmYMmskFdvn0FFcaPes=; b=bxnas0jwCeYfczOYqnkoV5yPxQ9eZeSKwDsM1p0p86DBDbcIwiNYSbdlev6L9XXHU0 L3Np2Rg5Y1mq2a2a1ygwekJvc0X+YVRDhZRrERdg8wGc1T6mhcPLJzWR3yP6gx+MDYAX fsPuDH3hjfz+TZhuh3C5pOdmXxaO2wXVtvyIVr2IDFXvjzaGvw9U97G3mzFAy8Wzdoo2 md0bDiLawy4vvXf8yniRlRkGRKtgrIRdI14Xs1/Z1EpUCue396lNQRIHzfsHtez40Kyb wzX+2Em4R3awMurqJgrKbfF/Z/DxpJqOisJZoKMH7+rKxZh7fsBMvNHgiH3p8TAy9guP Olrw== X-Gm-Message-State: ALKqPwfgvs7Aq67P49WRdZiJylGBNZN1Niv94Tef2ysVPFCIHVvsMNdn M54r2waUGSwMJGSjnTbyrA+k3g== X-Google-Smtp-Source: ADUXVKK/Nx4VD08CblBHDt+1r2iRNjGQIE66mLDoL7HHgRlY2Cpw54wrPfgX80dHOlN46TISJd0dpA== X-Received: by 2002:a17:902:1a6:: with SMTP id b35-v6mr11989167plb.80.1527874971939; Fri, 01 Jun 2018 10:42:51 -0700 (PDT) Received: from localhost.localdomain.localdomain (c-73-162-150-77.hsd1.ca.comcast.net. [73.162.150.77]) by smtp.gmail.com with ESMTPSA id v26-v6sm9600279pfe.13.2018.06.01.10.42.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 Jun 2018 10:42:51 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Fri, 1 Jun 2018 10:42:04 -0700 Message-Id: <1527874926-40450-15-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> References: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v3 14/16] ovn-controller: Incremental processing for address-set changes. 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: Han Zhou --- ovn/controller/lflow.c | 100 ++++++++++++++++++++++++++++++++++++++++ ovn/controller/lflow.h | 16 +++++++ ovn/controller/ovn-controller.c | 72 ++++++++++++++++++++++++++++- tests/ovn.at | 71 ++++++++++++++++++++++++++++ 4 files changed, 258 insertions(+), 1 deletion(-) diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c index a39e241..17c9f20 100644 --- a/ovn/controller/lflow.c +++ b/ovn/controller/lflow.c @@ -392,6 +392,106 @@ lflow_handle_changed_flows(struct ovn_desired_flow_table *flow_table, return ret; } +bool +lflow_handle_changed_ref(struct ovn_desired_flow_table *flow_table, + struct lflow_resource_ref *lfrr, + enum ref_type ref_type, + const char *ref_name, + struct controller_ctx *ctx, + const struct sbrec_chassis *chassis, + const struct chassis_index *chassis_index, + const struct hmap *local_datapaths, + struct ovn_extend_table *group_table, + struct ovn_extend_table *meter_table, + const struct shash *addr_sets, + const struct shash *port_groups, + struct sset *active_tunnels, + struct sset *local_lport_ids, + uint32_t *conj_id_ofs, + bool *changed) +{ + struct ref_lflow_node *rlfn = ref_lflow_lookup(&lfrr->ref_lflow_table, + ref_type, ref_name); + if (!rlfn) { + *changed = false; + return true; + } + VLOG_DBG("Handle changed lflow reference for resource type: %d," + " name: %s.", ref_type, ref_name); + *changed = false; + bool ret = true; + + hmap_remove(&lfrr->ref_lflow_table, &rlfn->node); + + struct lflow_ref_list_node *lrln, *next; + /* Detach the rlfn->ref_lflow_head nodes from the lfrr table and clean + * up all other nodes related to the lflows that uses the resource, + * so that the old nodes won't interfere with updating the lfrr table + * when reparsing the lflows. */ + LIST_FOR_EACH (lrln, ref_list, &rlfn->ref_lflow_head) { + ovs_list_remove(&lrln->lflow_list); + lflow_resource_destroy_lflow(lfrr, &lrln->lflow_uuid); + } + + struct hmap dhcp_opts = HMAP_INITIALIZER(&dhcp_opts); + struct hmap dhcpv6_opts = HMAP_INITIALIZER(&dhcpv6_opts); + const struct sbrec_dhcp_options *dhcp_opt_row; + SBREC_DHCP_OPTIONS_FOR_EACH (dhcp_opt_row, ctx->ovnsb_idl) { + dhcp_opt_add(&dhcp_opts, dhcp_opt_row->name, dhcp_opt_row->code, + dhcp_opt_row->type); + } + + + const struct sbrec_dhcpv6_options *dhcpv6_opt_row; + SBREC_DHCPV6_OPTIONS_FOR_EACH(dhcpv6_opt_row, ctx->ovnsb_idl) { + dhcp_opt_add(&dhcpv6_opts, dhcpv6_opt_row->name, dhcpv6_opt_row->code, + dhcpv6_opt_row->type); + } + + struct hmap nd_ra_opts = HMAP_INITIALIZER(&nd_ra_opts); + nd_ra_opts_init(&nd_ra_opts); + + /* Re-parse the related lflows. */ + LIST_FOR_EACH (lrln, ref_list, &rlfn->ref_lflow_head) { + const struct sbrec_logical_flow *lflow = + sbrec_logical_flow_get_for_uuid(ctx->ovnsb_idl, + &lrln->lflow_uuid); + if (!lflow) { + VLOG_DBG("Reprocess lflow "UUID_FMT" for resource type: %d," + " name: %s - not found.", + UUID_ARGS(&lrln->lflow_uuid), + ref_type, ref_name); + continue; + } + VLOG_DBG("Reprocess lflow "UUID_FMT" for resource type: %d," + " name: %s.", + UUID_ARGS(&lrln->lflow_uuid), + ref_type, ref_name); + ofctrl_remove_flows(flow_table, &lrln->lflow_uuid); + if (!consider_logical_flow(flow_table, lfrr, ctx, chassis_index, + lflow, local_datapaths, + group_table, meter_table, chassis, + &dhcp_opts, &dhcpv6_opts, &nd_ra_opts, + conj_id_ofs, addr_sets, port_groups, + active_tunnels, local_lport_ids)) { + ret = false; + break; + } + *changed = true; + } + + LIST_FOR_EACH_SAFE (lrln, next, ref_list, &rlfn->ref_lflow_head) { + ovs_list_remove(&lrln->ref_list); + free(lrln); + } + free(rlfn); + + dhcp_opts_destroy(&dhcp_opts); + dhcp_opts_destroy(&dhcpv6_opts); + nd_ra_opts_destroy(&nd_ra_opts); + return ret; +} + static bool update_conj_id_ofs(uint32_t *conj_id_ofs, uint32_t n_conjs) { diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h index bc6c7ac..a5c42f1 100644 --- a/ovn/controller/lflow.h +++ b/ovn/controller/lflow.h @@ -139,6 +139,22 @@ bool lflow_handle_changed_flows(struct ovn_desired_flow_table *, struct sset *active_tunnels, struct sset *local_lport_ids, uint32_t *conj_id_ofs); +bool lflow_handle_changed_ref(struct ovn_desired_flow_table *, + struct lflow_resource_ref *, + enum ref_type, + const char *ref_name, + struct controller_ctx *ctx, + const struct sbrec_chassis *chassis, + const struct chassis_index *chassis_index, + const struct hmap *local_datapaths, + struct ovn_extend_table *group_table, + struct ovn_extend_table *meter_table, + const struct shash *addr_sets, + const struct shash *port_groups, + struct sset *active_tunnels, + struct sset *local_lport_ids, + uint32_t *conj_id_ofs, + bool *changed); void lflow_destroy(void); #endif /* ovn/lflow.h */ diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 7d0bde5..953582f 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -1075,6 +1075,76 @@ flow_output_sb_multicast_group_handler(struct engine_node *node) } +static bool +flow_output_addr_sets_handler(struct engine_node *node) +{ + struct controller_ctx *ctx = (struct controller_ctx *)node->context; + struct ed_type_runtime_data *data = + (struct ed_type_runtime_data *)engine_get_input( + "runtime_data", node)->data; + struct hmap *local_datapaths = &data->local_datapaths; + struct sset *local_lport_ids = &data->local_lport_ids; + struct sset *active_tunnels = &data->active_tunnels; + struct chassis_index *chassis_index = &data->chassis_index; + struct shash *port_groups = &data->port_groups; + struct ed_type_addr_sets *as_data = + (struct ed_type_addr_sets *)engine_get_input("addr_sets", node)->data; + struct shash *addr_sets = &as_data->addr_sets; + const struct ovsrec_bridge *br_int = get_br_int(ctx); + const char *chassis_id = get_chassis_id(ctx->ovs_idl); + + const struct sbrec_chassis *chassis = NULL; + if (chassis_id) { + chassis = get_chassis(ctx->ovnsb_idl, chassis_id); + } + + ovs_assert(br_int && chassis); + + struct ed_type_flow_output *fo = + (struct ed_type_flow_output *)node->data; + struct ovn_desired_flow_table *flow_table = &fo->flow_table; + struct ovn_extend_table *group_table = &fo->group_table; + struct ovn_extend_table *meter_table = &fo->meter_table; + uint32_t *conj_id_ofs = &fo->conj_id_ofs; + struct lflow_resource_ref *lfrr = &fo->lflow_resource_ref; + + bool changed; + const char *as; + + SSET_FOR_EACH (as, &as_data->deleted) { + if (!lflow_handle_changed_ref(flow_table, lfrr, REF_TYPE_ADDRSET, + as, ctx, chassis, chassis_index, local_datapaths, + group_table, meter_table, addr_sets, port_groups, + active_tunnels, local_lport_ids, conj_id_ofs, + &changed)) { + return false; + } + node->changed = changed || node->changed; + } + SSET_FOR_EACH (as, &as_data->updated) { + if (!lflow_handle_changed_ref(flow_table, lfrr, REF_TYPE_ADDRSET, + as, ctx, chassis, chassis_index, local_datapaths, + group_table, meter_table, addr_sets, port_groups, + active_tunnels, local_lport_ids, conj_id_ofs, + &changed)) { + return false; + } + node->changed = changed || node->changed; + } + SSET_FOR_EACH (as, &as_data->new) { + if (!lflow_handle_changed_ref(flow_table, lfrr, REF_TYPE_ADDRSET, + as, ctx, chassis, chassis_index, local_datapaths, + group_table, meter_table, addr_sets, port_groups, + active_tunnels, local_lport_ids, conj_id_ofs, + &changed)) { + return false; + } + node->changed = changed || node->changed; + } + + return true; +} + int main(int argc, char *argv[]) { @@ -1156,7 +1226,7 @@ main(int argc, char *argv[]) engine_add_input(&en_addr_sets, &en_sb_address_set, NULL); - engine_add_input(&en_flow_output, &en_addr_sets, NULL); + engine_add_input(&en_flow_output, &en_addr_sets, flow_output_addr_sets_handler); engine_add_input(&en_flow_output, &en_runtime_data, NULL); engine_add_input(&en_flow_output, &en_ovs_port, NULL); diff --git a/tests/ovn.at b/tests/ovn.at index f12c24c..c933f70 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -10267,3 +10267,74 @@ $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets AT_CHECK([cat 2.packets], [0], []) AT_CLEANUP + +AT_SETUP([ovn -- Address Set Incremental Processing]) +AT_KEYWORDS([ovn_as_inc]) +AT_SKIP_IF([test $HAVE_PYTHON = no]) +ovn_start + +net_add n1 +sim_add hv1 +as hv1 +ovs-vsctl add-br br-phys +ovn_attach n1 br-phys 192.168.0.10 + +ovn-nbctl ls-add ls1 +for i in 1 2; do + ovn-nbctl lsp-add ls1 lp$i \ + -- lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.1.$i" + as hv1 ovs-vsctl \ + -- add-port br-int vif$i \ + -- set Interface vif$i \ + external-ids:iface-id=lp$i +done + +for i in 1 2 3; do + as1_uuid=`ovn-nbctl --wait=hv create addr name=as1` + as2_uuid=`ovn-nbctl --wait=hv create addr name=as2` + ovn-nbctl --wait=hv acl-add ls1 to-lport 200 \ + 'outport=="lp1" && ip4 && ip4.src == {$as1, $as2}' allow-related + ovn-nbctl --wait=hv set addr as1 addresses="10.1.2.10" + AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.10"], [0], [ignore]) + + # Update address set as1 + ovn-nbctl --wait=hv set addr as1 addresses="10.1.2.10 10.1.2.11" + AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.11"], [0], [ignore]) + + # Update address set as2 + ovn-nbctl --wait=hv set addr as2 addresses="10.1.2.12 10.1.2.13" + AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [0], [ignore]) + + # Add another ACL referencing as1 + n_flows_before=`ovs-ofctl dump-flows br-int | grep "10.1.2.10" | wc -l` + ovn-nbctl --wait=hv acl-add ls1 to-lport 200 \ + 'outport=="lp2" && ip4 && ip4.src == $as1' allow-related + n_flows_after=`ovs-ofctl dump-flows br-int | grep "10.1.2.10" | wc -l` + AT_CHECK([test $(expr $n_flows_before \* 2) = $n_flows_after], [0], [ignore]) + + # Remove an ACL + ovn-nbctl --wait=hv acl-del ls1 to-lport 200 \ + 'outport=="lp2" && ip4 && ip4.src == $as1' + n_flows_after=`ovs-ofctl dump-flows br-int | grep "10.1.2.10" | wc -l` + AT_CHECK([test $n_flows_before = $n_flows_after], [0], [ignore]) + + # Remove as1 while it is still used by an ACL, the lflows should be reparsed and + # parsing should fail. + ovn-nbctl --wait=hv destroy addr $as1_uuid + AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.10"], [1], [ignore]) + AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [1], [ignore]) + + # Recreate as1 + as1_uuid=`ovn-nbctl --wait=hv create addr name=as1` + AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [0], [ignore]) + + # Remove ACLs and address sets + ovn-nbctl --wait=hv destroy addr $as1_uuid -- destroy addr $as2_uuid + AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [1], [ignore]) + + ovn-nbctl --wait=hv acl-del ls1 +done + +# Gracefully terminate daemons +OVN_CLEANUP([hv1]) +AT_CLEANUP From patchwork Fri Jun 1 17:42:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 924273 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=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="tP8JTmF+"; dkim-atps=neutral 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 40yBgp2fyfz9ry1 for ; Sat, 2 Jun 2018 03:50:30 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 45E87F78; Fri, 1 Jun 2018 17:43:01 +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 15DB4F53 for ; Fri, 1 Jun 2018 17:42:54 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg0-f65.google.com (mail-pg0-f65.google.com [74.125.83.65]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 681016DB for ; Fri, 1 Jun 2018 17:42:53 +0000 (UTC) Received: by mail-pg0-f65.google.com with SMTP id e11-v6so2380987pgq.0 for ; Fri, 01 Jun 2018 10:42:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=oqyLAoavWGX+c+IWr0uc+EkrcP7ginDkxM0EVfeJZeQ=; b=tP8JTmF+Qnachj9b3wAqvLLGYx2CmmBjaWHpPsmrZswQNqmfTf7SOzTivkU/lEH3av eps0/htf5ABRObfz3KxC4ZtkEO08lPQ/PD4ViJrz/2lRN42rN+niZTTkPD43jycMB7SJ bcsMqgMUQC1XcR+ByZMMWsN7E2HRgGfI53v768ZtlF+0Zi1EgeijERDgqKM6+gnJX9yp 2Ngtl2x7nXfPQorjK1K3CSV7T6lnBhnwlYaK4IhXfDz50a+pAIAnGOCj/QeHJiJTqPF+ oWxTnYEuh6OAflA7bgOL+x8ync4fLDGe4oOIEohFgqAorFoNFGRbRH8BSn2tJsrrIA/Z lWQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=oqyLAoavWGX+c+IWr0uc+EkrcP7ginDkxM0EVfeJZeQ=; b=VvkujcypVJoSOkmA9Al2mvrLGIF8aJL6p3M2bjZKVeqaMCFjOf5/Fk98xwmFOu0chj a/hXHwmpEPhtQHAhF5LTb6pxLKrVzIoBnMytj5nHkd77ATe4z7MEhCMks3qy6Z0BKVjM 6UwVU6NOu9elo1LX3lH4QKqMpcDqEi2MVv3+MiOktkbdFLqP1DawCOHkh3Q9KjCpZyNC 0PQAhwdqoo81Knakinlln2MyQgtW46eDZRBmrJbQk/qVbrRURWfEvrcmciTlTW0R/MB1 7Zbh8lOU1a43Z7saTzvV1XNSRvIeZFxi/z0dIZl5rkgKdg8rxCDGFSuhe8K2dx78+G/x QWFw== X-Gm-Message-State: ALKqPwczgSUgXKvIAhKF6I0AICRkHMcv+uC2hx7tkgCVP9AOm+02SDsk HrmGyHZiZaZSj480SyC7RmgL0Q== X-Google-Smtp-Source: ADUXVKJY806SmabNu4KnCyCCNiitmWUbNb5rQHoXZADm2aSN/lFvPBw3usHKONTnMhsyLciP5qmpgA== X-Received: by 2002:a62:4353:: with SMTP id q80-v6mr11875704pfa.228.1527874972802; Fri, 01 Jun 2018 10:42:52 -0700 (PDT) Received: from localhost.localdomain.localdomain (c-73-162-150-77.hsd1.ca.comcast.net. [73.162.150.77]) by smtp.gmail.com with ESMTPSA id v26-v6sm9600279pfe.13.2018.06.01.10.42.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 Jun 2018 10:42:52 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Fri, 1 Jun 2018 10:42:05 -0700 Message-Id: <1527874926-40450-16-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> References: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v3 15/16] ovn-controller: Split port_groups from runtime_data. 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: Han Zhou --- ovn/controller/ovn-controller.c | 105 +++++++++++++++++++++++++++++++++------- 1 file changed, 87 insertions(+), 18 deletions(-) diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 953582f..aa32284 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -315,13 +315,25 @@ addr_sets_update(struct controller_ctx *ctx, struct shash *addr_sets, /* Iterate port groups in the southbound database. Create and update the * corresponding symtab entries as necessary. */ static void -port_groups_init(struct controller_ctx *ctx, struct shash *port_groups) +port_groups_update(struct controller_ctx *ctx, struct shash *port_groups, + struct sset *new, struct sset *deleted, + struct sset *updated) { const struct sbrec_port_group *pg; - SBREC_PORT_GROUP_FOR_EACH (pg, ctx->ovnsb_idl) { - expr_const_sets_add(port_groups, pg->name, - (const char *const *) pg->ports, - pg->n_ports, false); + SBREC_PORT_GROUP_FOR_EACH_TRACKED (pg, ctx->ovnsb_idl) { + if (sbrec_port_group_is_deleted(pg)) { + expr_const_sets_remove(port_groups, pg->name); + sset_add(deleted, pg->name); + } else { + expr_const_sets_add(port_groups, pg->name, + (const char *const *) pg->ports, + pg->n_ports, false); + if (sbrec_port_group_is_new(pg)) { + sset_add(new, pg->name); + } else { + sset_add(updated, pg->name); + } + } } } @@ -664,6 +676,53 @@ en_addr_sets_run(struct engine_node *node) || !sset_is_empty(&as->updated); } +struct ed_type_port_groups{ + struct shash port_groups; + struct sset new; + struct sset deleted; + struct sset updated; +}; + +static void +en_port_groups_init(struct engine_node *node) +{ + struct ed_type_port_groups *pg = (struct ed_type_port_groups *)node->data; + shash_init(&pg->port_groups); + sset_init(&pg->new); + sset_init(&pg->deleted); + sset_init(&pg->updated); +} + +static void +en_port_groups_cleanup(struct engine_node *node) +{ + struct ed_type_port_groups *pg = (struct ed_type_port_groups *)node->data; + expr_const_sets_destroy(&pg->port_groups); + shash_destroy(&pg->port_groups); + sset_destroy(&pg->new); + sset_destroy(&pg->deleted); + sset_destroy(&pg->updated); +} + +/* For en_port_groups, the run function handles changes since there is only + * one input */ +static void +en_port_groups_run(struct engine_node *node) +{ + struct controller_ctx *ctx = (struct controller_ctx *)node->context; + struct ed_type_port_groups *pg = (struct ed_type_port_groups *)node->data; + + sset_clear(&pg->new); + sset_clear(&pg->deleted); + sset_clear(&pg->updated); + + port_groups_update(ctx, &pg->port_groups, &pg->new, + &pg->deleted, &pg->updated); + + node->changed = !sset_is_empty(&pg->new) || !sset_is_empty(&pg->deleted) + || !sset_is_empty(&pg->updated); +} + struct ed_type_runtime_data { struct chassis_index chassis_index; @@ -681,7 +740,6 @@ struct ed_type_runtime_data { * _ */ struct sset local_lport_ids; struct sset active_tunnels; - struct shash port_groups; /* connection tracking zones. */ unsigned long ct_zone_bitmap[BITMAP_N_LONGS(MAX_CT_ZONES)]; @@ -699,7 +757,6 @@ en_runtime_data_init(struct engine_node *node) sset_init(&data->local_lports); sset_init(&data->local_lport_ids); sset_init(&data->active_tunnels); - shash_init(&data->port_groups); shash_init(&data->pending_ct_zones); simap_init(&data->ct_zones); @@ -715,9 +772,6 @@ en_runtime_data_cleanup(struct engine_node *node) struct ed_type_runtime_data *data = (struct ed_type_runtime_data *)node->data; - expr_const_sets_destroy(&data->port_groups); - shash_destroy(&data->port_groups); - chassis_index_destroy(&data->chassis_index); sset_destroy(&data->local_lports); @@ -747,7 +801,6 @@ en_runtime_data_run(struct engine_node *node) struct sset *local_lport_ids = &data->local_lport_ids; struct sset *active_tunnels = &data->active_tunnels; struct chassis_index *chassis_index = &data->chassis_index; - struct shash *port_groups = &data->port_groups; unsigned long *ct_zone_bitmap = data->ct_zone_bitmap; struct shash *pending_ct_zones = &data->pending_ct_zones; struct simap *ct_zones = &data->ct_zones; @@ -768,7 +821,6 @@ en_runtime_data_run(struct engine_node *node) sset_destroy(local_lport_ids); sset_destroy(active_tunnels); chassis_index_destroy(chassis_index); - expr_const_sets_destroy(port_groups); sset_init(local_lports); sset_init(local_lport_ids); sset_init(active_tunnels); @@ -789,7 +841,6 @@ en_runtime_data_run(struct engine_node *node) chassis_index, active_tunnels, local_datapaths, local_lports, local_lport_ids); - port_groups_init(ctx, port_groups); update_ct_zones(local_lports, local_datapaths, ct_zones, ct_zone_bitmap, pending_ct_zones); @@ -870,13 +921,17 @@ en_flow_output_run(struct engine_node *node) struct sset *local_lport_ids = &rt_data->local_lport_ids; struct sset *active_tunnels = &rt_data->active_tunnels; struct chassis_index *chassis_index = &rt_data->chassis_index; - struct shash *port_groups = &rt_data->port_groups; struct simap *ct_zones = &rt_data->ct_zones; struct ed_type_addr_sets *as_data = (struct ed_type_addr_sets *)engine_get_input("addr_sets", node)->data; struct shash *addr_sets = &as_data->addr_sets; + struct ed_type_port_groups *pg_data = + (struct ed_type_port_groups *)engine_get_input( + "port_groups", node)->data; + struct shash *port_groups = &pg_data->port_groups; + const struct ovsrec_bridge *br_int = get_br_int(ctx); const char *chassis_id = get_chassis_id(ctx->ovs_idl); @@ -932,11 +987,16 @@ flow_output_sb_logical_flow_handler(struct engine_node *node) struct sset *local_lport_ids = &data->local_lport_ids; struct sset *active_tunnels = &data->active_tunnels; struct chassis_index *chassis_index = &data->chassis_index; - struct shash *port_groups = &data->port_groups; + struct ed_type_addr_sets *as_data = (struct ed_type_addr_sets *)engine_get_input("addr_sets", node)->data; struct shash *addr_sets = &as_data->addr_sets; + struct ed_type_port_groups *pg_data = + (struct ed_type_port_groups *)engine_get_input( + "port_groups", node)->data; + struct shash *port_groups = &pg_data->port_groups; + const struct ovsrec_bridge *br_int = get_br_int(ctx); const char *chassis_id = get_chassis_id(ctx->ovs_idl); @@ -1086,10 +1146,16 @@ flow_output_addr_sets_handler(struct engine_node *node) struct sset *local_lport_ids = &data->local_lport_ids; struct sset *active_tunnels = &data->active_tunnels; struct chassis_index *chassis_index = &data->chassis_index; - struct shash *port_groups = &data->port_groups; + struct ed_type_addr_sets *as_data = (struct ed_type_addr_sets *)engine_get_input("addr_sets", node)->data; struct shash *addr_sets = &as_data->addr_sets; + + struct ed_type_port_groups *pg_data = + (struct ed_type_port_groups *)engine_get_input( + "port_groups", node)->data; + struct shash *port_groups = &pg_data->port_groups; + const struct ovsrec_bridge *br_int = get_br_int(ctx); const char *chassis_id = get_chassis_id(ctx->ovs_idl); @@ -1202,6 +1268,7 @@ main(int argc, char *argv[]) struct ed_type_runtime_data ed_runtime_data; struct ed_type_flow_output ed_flow_output; struct ed_type_addr_sets ed_addr_sets; + struct ed_type_port_groups ed_port_groups; ENGINE_NODE_SB(chassis, "chassis", &ctx); ENGINE_NODE_SB(encap, "encap", &ctx); @@ -1221,12 +1288,15 @@ main(int argc, char *argv[]) ENGINE_NODE_OVS(interface, "ovs_table_interface", &ctx); ENGINE_NODE(addr_sets, "addr_sets", &ctx); + ENGINE_NODE(port_groups, "port_groups", &ctx); ENGINE_NODE(runtime_data, "runtime_data", &ctx); ENGINE_NODE(flow_output, "flow_output", &ctx); engine_add_input(&en_addr_sets, &en_sb_address_set, NULL); + engine_add_input(&en_port_groups, &en_sb_port_group, NULL); engine_add_input(&en_flow_output, &en_addr_sets, flow_output_addr_sets_handler); + engine_add_input(&en_flow_output, &en_port_groups, NULL); engine_add_input(&en_flow_output, &en_runtime_data, NULL); engine_add_input(&en_flow_output, &en_ovs_port, NULL); @@ -1248,7 +1318,6 @@ main(int argc, char *argv[]) engine_add_input(&en_runtime_data, &en_ovs_interface, NULL); engine_add_input(&en_runtime_data, &en_sb_chassis, NULL); - engine_add_input(&en_runtime_data, &en_sb_port_group, NULL); engine_add_input(&en_runtime_data, &en_sb_datapath_binding, NULL); engine_add_input(&en_runtime_data, &en_sb_port_binding, runtime_data_sb_port_binding_handler); engine_add_input(&en_runtime_data, &en_sb_gateway_chassis, NULL); @@ -1354,7 +1423,7 @@ main(int argc, char *argv[]) if (pending_pkt.conn) { if (br_int && chassis) { char *error = ofctrl_inject_pkt(br_int, pending_pkt.flow_s, - &ed_runtime_data.port_groups, + &ed_port_groups.port_groups, &ed_addr_sets.addr_sets); if (error) { unixctl_command_reply_error(pending_pkt.conn, error); From patchwork Fri Jun 1 17:42:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 924274 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=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="l6gZp6Ko"; dkim-atps=neutral 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 40yBhL4nlVz9ry1 for ; Sat, 2 Jun 2018 03:50:58 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 7C5A9F83; Fri, 1 Jun 2018 17:43:02 +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 839A4F5B for ; Fri, 1 Jun 2018 17:42:54 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f47.google.com (mail-pl0-f47.google.com [209.85.160.47]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 1B814CF for ; Fri, 1 Jun 2018 17:42:54 +0000 (UTC) Received: by mail-pl0-f47.google.com with SMTP id 31-v6so5792336plc.4 for ; Fri, 01 Jun 2018 10:42:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=44QK/9LrgGypZPTJAxFXSvlMhZw+b0XZbt1AMTzZPK0=; b=l6gZp6KoHybqSNzJwVIDnrj2Dsv+YEJN2T3p9yhIxWMDjGsnjHdDEKGYqiP474fgN2 36vDxN/8uhMbWTcvkZDQGjShJ3AOP6WJO/DExSiwc5LvoM4dTZtm0HFmQSSFfXSOMF5P XiP3yjaKZHVqkjSeVzOuupnSsgl++mVVVnH6q/LsP0stoN8XKMeICir6PozzRIqsnwjJ 2LsfI8eM3pWy8s1wt2LLvBQ3ikFLoGhL2uLUWZ5JSf9O4X8MYgQnMWOGLsoFulom2RGw 6QNwO13CSjyeZxf1k6AeNgvVOJe/VXXK+ci22/i9WkhRjjTTWOfmUd3WnyzKGBnzexZr G/SA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=44QK/9LrgGypZPTJAxFXSvlMhZw+b0XZbt1AMTzZPK0=; b=YZAxcqf903x6l9aM++aAn+RU5PrJG6R9KAMMR5HqbjlrUwhts5VxhXo/5qLOIFKAD9 bKQc4nsxeQRpxh2ijbR7N+qP2idockyRBhtK30GAuaH3LrtoBsXtB4QTGdDVcFMBYSjx NSAjC+sfGSwkQaK42dUcc+WMotArW2rq30DWW7nAHDE24ksctYm92NAtjv8vNsizKTtd VN738Cbi/cUabottnzNTTJqaamuMOePCkujS68KXBh2QsltfXLlQjH0ZpFr4NFN6ticN gZOG5ECq/WwI16GsJuwhnveuy/cSSruBxeS7lLl0i7d6e1Gdk8tsCmfuMR9i7wRI2pnf Xt6A== X-Gm-Message-State: ALKqPwdc8gD/al/HVtqNi/q5moDqjhA6LmCvI19K5Vk/TFhJMH1pr6N4 LVg5xvEZcTFBk2cBSex64rgzIg== X-Google-Smtp-Source: ADUXVKLjgfe1UYr5FFFQhETlBHPyN1SSQw5pU2VXRrvEurM9H5q7YoTtUayJB4iXUp9ah7IgDyPK9Q== X-Received: by 2002:a17:902:6bc7:: with SMTP id m7-v6mr11765286plt.162.1527874973507; Fri, 01 Jun 2018 10:42:53 -0700 (PDT) Received: from localhost.localdomain.localdomain (c-73-162-150-77.hsd1.ca.comcast.net. [73.162.150.77]) by smtp.gmail.com with ESMTPSA id v26-v6sm9600279pfe.13.2018.06.01.10.42.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 Jun 2018 10:42:53 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Fri, 1 Jun 2018 10:42:06 -0700 Message-Id: <1527874926-40450-17-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> References: <1527874926-40450-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v3 16/16] ovn-controller: Incremental processing for port-group changes. 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: Han Zhou --- ovn/controller/lflow.h | 3 ++- ovn/controller/ovn-controller.c | 54 ++++++++++++++++++++++++++++++++--------- 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h index a5c42f1..b20838a 100644 --- a/ovn/controller/lflow.h +++ b/ovn/controller/lflow.h @@ -67,7 +67,8 @@ struct uuid; #define LOG_PIPELINE_LEN 24 enum ref_type { - REF_TYPE_ADDRSET + REF_TYPE_ADDRSET, + REF_TYPE_PORTGROUP }; /* Maintains the relationship for a pair of named resource and diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index aa32284..02a64e0 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -1136,7 +1136,8 @@ flow_output_sb_multicast_group_handler(struct engine_node *node) } static bool -flow_output_addr_sets_handler(struct engine_node *node) +_flow_output_resource_ref_handler(struct engine_node *node, + enum ref_type ref_type) { struct controller_ctx *ctx = (struct controller_ctx *)node->context; struct ed_type_runtime_data *data = @@ -1175,11 +1176,28 @@ flow_output_addr_sets_handler(struct engine_node *node) struct lflow_resource_ref *lfrr = &fo->lflow_resource_ref; bool changed; - const char *as; + const char *ref_name; + struct sset *new, *updated, *deleted; + + switch (ref_type) { + case REF_TYPE_ADDRSET: + new = &as_data->new; + updated = &as_data->updated; + deleted = &as_data->deleted; + break; + case REF_TYPE_PORTGROUP: + new = &pg_data->new; + updated = &pg_data->updated; + deleted = &pg_data->deleted; + break; + default: + OVS_NOT_REACHED(); + } + - SSET_FOR_EACH (as, &as_data->deleted) { - if (!lflow_handle_changed_ref(flow_table, lfrr, REF_TYPE_ADDRSET, - as, ctx, chassis, chassis_index, local_datapaths, + SSET_FOR_EACH (ref_name, deleted) { + if (!lflow_handle_changed_ref(flow_table, lfrr, ref_type, ref_name, + ctx, chassis, chassis_index, local_datapaths, group_table, meter_table, addr_sets, port_groups, active_tunnels, local_lport_ids, conj_id_ofs, &changed)) { @@ -1187,9 +1205,9 @@ flow_output_addr_sets_handler(struct engine_node *node) } node->changed = changed || node->changed; } - SSET_FOR_EACH (as, &as_data->updated) { - if (!lflow_handle_changed_ref(flow_table, lfrr, REF_TYPE_ADDRSET, - as, ctx, chassis, chassis_index, local_datapaths, + SSET_FOR_EACH (ref_name, updated) { + if (!lflow_handle_changed_ref(flow_table, lfrr, ref_type, ref_name, + ctx, chassis, chassis_index, local_datapaths, group_table, meter_table, addr_sets, port_groups, active_tunnels, local_lport_ids, conj_id_ofs, &changed)) { @@ -1197,9 +1215,9 @@ flow_output_addr_sets_handler(struct engine_node *node) } node->changed = changed || node->changed; } - SSET_FOR_EACH (as, &as_data->new) { - if (!lflow_handle_changed_ref(flow_table, lfrr, REF_TYPE_ADDRSET, - as, ctx, chassis, chassis_index, local_datapaths, + SSET_FOR_EACH (ref_name, new) { + if (!lflow_handle_changed_ref(flow_table, lfrr, ref_type, ref_name, + ctx, chassis, chassis_index, local_datapaths, group_table, meter_table, addr_sets, port_groups, active_tunnels, local_lport_ids, conj_id_ofs, &changed)) { @@ -1211,6 +1229,18 @@ flow_output_addr_sets_handler(struct engine_node *node) return true; } +static bool +flow_output_addr_sets_handler(struct engine_node *node) +{ + return _flow_output_resource_ref_handler(node, REF_TYPE_ADDRSET); +} + +static bool +flow_output_port_groups_handler(struct engine_node *node) +{ + return _flow_output_resource_ref_handler(node, REF_TYPE_PORTGROUP); +} + int main(int argc, char *argv[]) { @@ -1296,7 +1326,7 @@ main(int argc, char *argv[]) engine_add_input(&en_port_groups, &en_sb_port_group, NULL); engine_add_input(&en_flow_output, &en_addr_sets, flow_output_addr_sets_handler); - engine_add_input(&en_flow_output, &en_port_groups, NULL); + engine_add_input(&en_flow_output, &en_port_groups, flow_output_port_groups_handler); engine_add_input(&en_flow_output, &en_runtime_data, NULL); engine_add_input(&en_flow_output, &en_ovs_port, NULL);