From patchwork Fri Jan 14 18:01:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 1580226 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=eQRiQwRN; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=smtp2.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4Jb8J43p4wz9ssD for ; Sat, 15 Jan 2022 05:01:40 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id D44B0404A8; Fri, 14 Jan 2022 18:01:37 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id wg7294xjoa9y; Fri, 14 Jan 2022 18:01:35 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp2.osuosl.org (Postfix) with ESMTPS id A7F7940477; Fri, 14 Jan 2022 18:01:34 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id C1658C0070; Fri, 14 Jan 2022 18:01:33 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 54EBEC002F for ; Fri, 14 Jan 2022 18:01:31 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 3199A40477 for ; Fri, 14 Jan 2022 18:01:31 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8Yji0bEdsmJe for ; Fri, 14 Jan 2022 18:01:29 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by smtp2.osuosl.org (Postfix) with ESMTPS id 01A3B400A8 for ; Fri, 14 Jan 2022 18:01:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1642183288; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/WejInkl0kpEEYH0tqnukUaoPDmjvCnt0L1LRfBuyls=; b=eQRiQwRNQPQUAsisdPi6mTNnVO29Fnu9pmmYKVHu0sPjssoGc/+Y5BKsES04m+ClroTjo1 Srgdd3DEkgNPhLKdKKOLMxZ4ckg0nwfsKPpxJ1CAuWM7Mfu2NzdyY7Dkl0tjdjYFvk9csY LXK79ALSAMG7r6hy2CscCMYHmCL4OAo= Received: from mail-qk1-f200.google.com (mail-qk1-f200.google.com [209.85.222.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-482-ntzYRDhlP02kX7T8_gDFYg-1; Fri, 14 Jan 2022 13:01:26 -0500 X-MC-Unique: ntzYRDhlP02kX7T8_gDFYg-1 Received: by mail-qk1-f200.google.com with SMTP id 81-20020a370454000000b00478f3a61beeso7209818qke.18 for ; Fri, 14 Jan 2022 10:01:26 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/WejInkl0kpEEYH0tqnukUaoPDmjvCnt0L1LRfBuyls=; b=dJqOSsPk9iHLN8kOSIsfwQnPwaSsJ6uDkja8XLR421OC4YD8vUCh1SouI30loiCjvs QQynXjQxA4bk5puDBUHa0rpX/11YTtV4djgxGNYlm2Q1pQT87pM7Z8d4jwNl9DvM3qSS A3ij/CsOOcISAZNX1oaMxcksPCG0fy1TqIP8TvhZZ7hDNUhlm1s97UhP0vyFICnbQamK 5YCb/Xkky/lXJ/QRHrLIyt0tmjcggLKj59TZpqRgUkQ4vW59g/fTPDL+LRK2BXjcDCb1 XJxoTETe99abhJoJJOcwG4TmYqN1Z+ycwBqRoPnb36vqXtTcfBx5o41zq2grS/Ua2CEe UJcg== X-Gm-Message-State: AOAM532SAZpM03oCxDmLP4EQT+pf0PMsoiFsTG4vnvr7YUJk3PHbLhyZ r5vFz1haJ80tvFwihbPimQloWp+Y0jPd/Vz4gSg42/ggNRjTUsCesUakAbTD2438aTGB4tXLACt DQbg5BlMb3g9/56UNwPFN1XHcNpL/VXidDNANKDuxl8XxMmJuS7U5qyD1H5t73ELSk93m2MhMFF F+x/Hg X-Received: by 2002:a05:620a:2990:: with SMTP id r16mr950236qkp.463.1642183285515; Fri, 14 Jan 2022 10:01:25 -0800 (PST) X-Google-Smtp-Source: ABdhPJxY/mZRJ0yc1TfKnCWM+uMfPrUPeEyIE6D8pbUOAz6HZnjcvtD+9l2uJjSjpyTvcxZbtCFDgg== X-Received: by 2002:a05:620a:2990:: with SMTP id r16mr950173qkp.463.1642183284780; Fri, 14 Jan 2022 10:01:24 -0800 (PST) Received: from lore-desk.redhat.com (net-93-146-37-237.cust.vodafonedsl.it. [93.146.37.237]) by smtp.gmail.com with ESMTPSA id b6sm4165824qtk.91.2022.01.14.10.01.23 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jan 2022 10:01:24 -0800 (PST) From: Lorenzo Bianconi To: ovs-dev@openvswitch.org Date: Fri, 14 Jan 2022 19:01:17 +0100 Message-Id: <4f52f1557e2c4e6586f9045c2a2fdc68ba76a370.1642182763.git.lorenzo.bianconi@redhat.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=lorenzo.bianconi@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH v2 ovn 1/3] inc-proc-eng: move inc-proc code in an isolated strucuture X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Remove global state variable and move move inc-proc code in an isolated strucuture. This is a preliminary patch to add the capability to run multiple inc-proc engines. Signed-off-by: Lorenzo Bianconi --- controller/ovn-controller.c | 65 ++++++----- lib/inc-proc-eng.c | 226 +++++++++++++++++++++++------------- lib/inc-proc-eng.h | 42 +++++-- northd/en-lflow.c | 2 +- northd/en-northd.c | 2 +- northd/inc-proc-northd.c | 30 ++--- 6 files changed, 231 insertions(+), 136 deletions(-) diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c index 5069aedfc..86cb6f769 100644 --- a/controller/ovn-controller.c +++ b/controller/ovn-controller.c @@ -114,6 +114,8 @@ static unixctl_cb_func debug_delay_nb_cfg_report; #define OVS_NB_CFG_TS_NAME "ovn-nb-cfg-ts" #define OVS_STARTUP_TS_NAME "ovn-startup-ts" +static struct engine *flow_engine; + static char *parse_options(int argc, char *argv[]); OVS_NO_RETURN static void usage(void); @@ -557,7 +559,7 @@ update_sb_db(struct ovsdb_idl *ovs_idl, struct ovsdb_idl *ovnsb_idl, } if (reset_ovnsb_idl_min_index && *reset_ovnsb_idl_min_index) { VLOG_INFO("Resetting southbound database cluster state"); - engine_set_force_recompute(true); + engine_set_force_recompute(flow_engine, true); ovsdb_idl_reset_min_index(ovnsb_idl); *reset_ovnsb_idl_min_index = false; } @@ -1011,7 +1013,8 @@ en_ofctrl_is_connected_cleanup(void *data OVS_UNUSED) static void en_ofctrl_is_connected_run(struct engine_node *node, void *data) { - struct controller_engine_ctx *ctrl_ctx = engine_get_context()->client_ctx; + struct controller_engine_ctx *ctrl_ctx = + engine_get_context(flow_engine)->client_ctx; struct ed_type_ofctrl_is_connected *of_data = data; if (of_data->connected != ofctrl_is_connected()) { of_data->connected = !of_data->connected; @@ -1226,10 +1229,11 @@ init_binding_ctx(struct engine_node *node, engine_get_input("SB_port_binding", node), "datapath"); - struct controller_engine_ctx *ctrl_ctx = engine_get_context()->client_ctx; + struct controller_engine_ctx *ctrl_ctx = + engine_get_context(flow_engine)->client_ctx; - b_ctx_in->ovnsb_idl_txn = engine_get_context()->ovnsb_idl_txn; - b_ctx_in->ovs_idl_txn = engine_get_context()->ovs_idl_txn; + b_ctx_in->ovnsb_idl_txn = engine_get_context(flow_engine)->ovnsb_idl_txn; + b_ctx_in->ovs_idl_txn = engine_get_context(flow_engine)->ovs_idl_txn; b_ctx_in->sbrec_datapath_binding_by_key = sbrec_datapath_binding_by_key; b_ctx_in->sbrec_port_binding_by_datapath = sbrec_port_binding_by_datapath; b_ctx_in->sbrec_port_binding_by_name = sbrec_port_binding_by_name; @@ -2387,7 +2391,8 @@ en_lflow_output_run(struct engine_node *node, void *data) lflow_conj_ids_clear(&fo->conj_ids); } - struct controller_engine_ctx *ctrl_ctx = engine_get_context()->client_ctx; + struct controller_engine_ctx *ctrl_ctx = + engine_get_context(flow_engine)->client_ctx; fo->pd.lflow_cache = ctrl_ctx->lflow_cache; @@ -3040,7 +3045,7 @@ check_northd_version(struct ovsdb_idl *ovs_idl, struct ovsdb_idl *ovnsb_idl, * full recompute. */ if (version_mismatch) { - engine_set_force_recompute(true); + engine_set_force_recompute(flow_engine, true); } version_mismatch = false; return true; @@ -3206,6 +3211,8 @@ main(int argc, char *argv[]) stopwatch_create(BFD_RUN_STOPWATCH_NAME, SW_MS); stopwatch_create(VIF_PLUG_RUN_STOPWATCH_NAME, SW_MS); + engine_init_global(); + /* Define inc-proc-engine nodes. */ ENGINE_NODE_WITH_CLEAR_TRACK_DATA_IS_VALID(ct_zones, "ct_zones"); ENGINE_NODE_WITH_CLEAR_TRACK_DATA(runtime_data, "runtime_data"); @@ -3344,7 +3351,7 @@ main(int argc, char *argv[]) .sb_idl = ovnsb_idl_loop.idl, .ovs_idl = ovs_idl_loop.idl, }; - engine_init(&en_flow_output, &engine_arg); + flow_engine = engine_new(&en_flow_output, &engine_arg, "flow_engine"); engine_ovsdb_node_add_index(&en_sb_chassis, "name", sbrec_chassis_by_name); engine_ovsdb_node_add_index(&en_sb_multicast_group, "name_datapath", @@ -3396,7 +3403,7 @@ main(int argc, char *argv[]) unixctl_command_register("recompute", "[deprecated]", 0, 0, engine_recompute_cmd, - NULL); + flow_engine); unixctl_command_register("lflow-cache/flush", "", 0, 0, lflow_cache_flush_cmd, &lflow_output_data->pd); @@ -3480,7 +3487,7 @@ main(int argc, char *argv[]) goto loop_done; } - engine_init_run(); + engine_init_run(flow_engine); struct ovsdb_idl_txn *ovs_idl_txn = ovsdb_idl_loop_run(&ovs_idl_loop); unsigned int new_ovs_cond_seqno @@ -3488,7 +3495,7 @@ main(int argc, char *argv[]) if (new_ovs_cond_seqno != ovs_cond_seqno) { if (!new_ovs_cond_seqno) { VLOG_INFO("OVS IDL reconnected, force recompute."); - engine_set_force_recompute(true); + engine_set_force_recompute(flow_engine, true); } ovs_cond_seqno = new_ovs_cond_seqno; } @@ -3506,7 +3513,7 @@ main(int argc, char *argv[]) if (new_ovnsb_cond_seqno != ovnsb_cond_seqno) { if (!new_ovnsb_cond_seqno) { VLOG_INFO("OVNSB IDL reconnected, force recompute."); - engine_set_force_recompute(true); + engine_set_force_recompute(flow_engine, true); vif_plug_reset_idl_prime_counter(); } ovnsb_cond_seqno = new_ovnsb_cond_seqno; @@ -3518,7 +3525,7 @@ main(int argc, char *argv[]) .client_ctx = &ctrl_engine_ctx }; - engine_set_context(&eng_ctx); + engine_set_context(flow_engine, &eng_ctx); bool northd_version_match = check_northd_version(ovs_idl_loop.idl, ovnsb_idl_loop.idl, @@ -3584,7 +3591,7 @@ main(int argc, char *argv[]) &br_int_dp->capabilities : NULL, br_int ? br_int->name : NULL)) { VLOG_INFO("OVS feature set changed, force recompute."); - engine_set_force_recompute(true); + engine_set_force_recompute(flow_engine, true); } if (br_int) { @@ -3619,9 +3626,9 @@ main(int argc, char *argv[]) * this round of engine_run and continue processing * acculated changes incrementally later when * ofctrl_can_put() returns true. */ - engine_run(false); + engine_run(flow_engine, false); } else { - engine_run(true); + engine_run(flow_engine, true); } } else { /* Even if there's no SB DB transaction available, @@ -3630,7 +3637,7 @@ main(int argc, char *argv[]) * If a recompute is required, the engine will abort, * triggerring a full run in the next iteration. */ - engine_run(false); + engine_run(flow_engine, false); } stopwatch_stop(CONTROLLER_LOOP_STOPWATCH_NAME, time_msec()); @@ -3775,24 +3782,24 @@ main(int argc, char *argv[]) } - if (!engine_has_run()) { - if (engine_need_run()) { + if (!engine_has_run(flow_engine)) { + if (engine_need_run(flow_engine)) { VLOG_DBG("engine did not run, force recompute next time: " "br_int %p, chassis %p", br_int, chassis); - engine_set_force_recompute(true); + engine_set_force_recompute(flow_engine, 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 if (engine_aborted()) { + } else if (engine_aborted(flow_engine)) { VLOG_DBG("engine was aborted, force recompute next time: " "br_int %p, chassis %p", br_int, chassis); - engine_set_force_recompute(true); + engine_set_force_recompute(flow_engine, true); poll_immediate_wake(); } else { - engine_set_force_recompute(false); + engine_set_force_recompute(flow_engine, false); } store_nb_cfg(ovnsb_idl_txn, ovs_idl_txn, chassis_private, @@ -3846,7 +3853,7 @@ main(int argc, char *argv[]) if (!ovsdb_idl_loop_commit_and_wait(&ovnsb_idl_loop)) { VLOG_INFO("OVNSB commit failed, force recompute next time."); - engine_set_force_recompute(true); + engine_set_force_recompute(flow_engine, true); } int ovs_txn_status = ovsdb_idl_loop_commit_and_wait(&ovs_idl_loop); @@ -3896,8 +3903,8 @@ loop_done: } } - engine_set_context(NULL); - engine_cleanup(); + engine_set_context(flow_engine, NULL); + engine_cleanup(flow_engine); /* It's time to exit. Clean up the databases if we are not restarting */ if (!restart) { @@ -4152,9 +4159,9 @@ inject_pkt(struct unixctl_conn *conn, int argc OVS_UNUSED, static void engine_recompute_cmd(struct unixctl_conn *conn OVS_UNUSED, int argc OVS_UNUSED, - const char *argv[] OVS_UNUSED, void *arg OVS_UNUSED) + const char *argv[] OVS_UNUSED, void *arg) { - engine_trigger_recompute(); + engine_trigger_recompute(arg); unixctl_command_reply(conn, NULL); } @@ -4166,7 +4173,7 @@ lflow_cache_flush_cmd(struct unixctl_conn *conn OVS_UNUSED, VLOG_INFO("User triggered lflow cache flush."); struct lflow_output_persistent_data *fo_pd = arg_; lflow_cache_flush(fo_pd->lflow_cache); - engine_set_force_recompute(true); + engine_set_force_recompute(flow_engine, true); poll_immediate_wake(); unixctl_command_reply(conn, NULL); } diff --git a/lib/inc-proc-eng.c b/lib/inc-proc-eng.c index 2958a55e3..a4798efb7 100644 --- a/lib/inc-proc-eng.c +++ b/lib/inc-proc-eng.c @@ -33,12 +33,7 @@ VLOG_DEFINE_THIS_MODULE(inc_proc_eng); -static bool engine_force_recompute = false; -static bool engine_run_aborted = false; -static const struct engine_context *engine_context; - -static struct engine_node **engine_nodes; -static size_t engine_n_nodes; +static struct ovs_list engines = OVS_LIST_INITIALIZER(&engines); static const char *engine_node_state_name[EN_STATE_MAX] = { [EN_STALE] = "Stale", @@ -52,21 +47,21 @@ engine_recompute(struct engine_node *node, bool allowed, const char *reason_fmt, ...) OVS_PRINTF_FORMAT(3, 4); void -engine_set_force_recompute(bool val) +engine_set_force_recompute(struct engine *e, bool val) { - engine_force_recompute = val; + e->engine_force_recompute = val; } const struct engine_context * -engine_get_context(void) +engine_get_context(struct engine *e) { - return engine_context; + return e->engine_context; } void -engine_set_context(const struct engine_context *ctx) +engine_set_context(struct engine *e, const struct engine_context *ctx) { - engine_context = ctx; + e->engine_context = ctx; } /* Builds the topologically sorted 'sorted_nodes' array starting from @@ -113,30 +108,53 @@ static void engine_clear_stats(struct unixctl_conn *conn, int argc OVS_UNUSED, const char *argv[] OVS_UNUSED, void *arg OVS_UNUSED) { - for (size_t i = 0; i < engine_n_nodes; i++) { - struct engine_node *node = engine_nodes[i]; + const char *target = argc == 2 ? argv[1] : NULL; + struct ds reply = DS_EMPTY_INITIALIZER; + struct engine *e; + + ds_put_format(&reply, "no %s engine found", target ? target : ""); + LIST_FOR_EACH (e, node, &engines) { + for (size_t i = 0; i < e->engine_n_nodes; i++) { + struct engine_node *node = e->engine_nodes[i]; - memset(&node->stats, 0, sizeof node->stats); + if (target && strcmp(target, e->name)) { + continue; + } + memset(&node->stats, 0, sizeof node->stats); + ds_clear(&reply); + } } - unixctl_command_reply(conn, NULL); + + unixctl_command_reply(conn, ds_cstr(&reply)); + ds_destroy(&reply); } static void -engine_dump_stats(struct unixctl_conn *conn, int argc OVS_UNUSED, +engine_dump_stats(struct unixctl_conn *conn, int argc, const char *argv[] OVS_UNUSED, void *arg OVS_UNUSED) { + const char *target = argc == 2 ? argv[1] : NULL; struct ds dump = DS_EMPTY_INITIALIZER; + struct engine *e; - for (size_t i = 0; i < engine_n_nodes; i++) { - struct engine_node *node = engine_nodes[i]; + LIST_FOR_EACH (e, node, &engines) { + for (size_t i = 0; i < e->engine_n_nodes; i++) { + struct engine_node *node = e->engine_nodes[i]; - ds_put_format(&dump, - "Node: %s\n" - "- recompute: %12"PRIu64"\n" - "- compute: %12"PRIu64"\n" - "- abort: %12"PRIu64"\n", - node->name, node->stats.recompute, - node->stats.compute, node->stats.abort); + if (target && strcmp(target, e->name)) { + continue; + } + ds_put_format(&dump, + "Node: %s\n" + "- recompute: %12"PRIu64"\n" + "- compute: %12"PRIu64"\n" + "- abort: %12"PRIu64"\n", + node->name, node->stats.recompute, + node->stats.compute, node->stats.abort); + } + } + if (ds_last(&dump) == EOF) { + ds_put_format(&dump, "no %s engine found", target ? target : ""); } unixctl_command_reply(conn, ds_cstr(&dump)); @@ -148,48 +166,92 @@ engine_trigger_recompute_cmd(struct unixctl_conn *conn, int argc OVS_UNUSED, const char *argv[] OVS_UNUSED, void *arg OVS_UNUSED) { - engine_trigger_recompute(); - unixctl_command_reply(conn, NULL); + const char *target = argc == 2 ? argv[1] : NULL; + struct ds reply = DS_EMPTY_INITIALIZER; + struct engine *e; + + ds_put_format(&reply, "no %s engine found", target ? target : ""); + LIST_FOR_EACH (e, node, &engines) { + if (target && strcmp(target, e->name)) { + continue; + } + engine_trigger_recompute(e); + ds_clear(&reply); + } + + unixctl_command_reply(conn, ds_cstr(&reply)); + ds_destroy(&reply); } -void -engine_init(struct engine_node *node, struct engine_arg *arg) +static void +engine_list_engines(struct unixctl_conn *conn, int argc OVS_UNUSED, + const char *argv[] OVS_UNUSED, + void *arg OVS_UNUSED) { - engine_nodes = engine_get_nodes(node, &engine_n_nodes); + struct ds reply = DS_EMPTY_INITIALIZER; + struct engine *e; - for (size_t i = 0; i < engine_n_nodes; i++) { - if (engine_nodes[i]->init) { - engine_nodes[i]->data = - engine_nodes[i]->init(engine_nodes[i], arg); - } else { - engine_nodes[i]->data = NULL; - } + LIST_FOR_EACH (e, node, &engines) { + ds_put_format(&reply, "%s\n", e->name); } + unixctl_command_reply(conn, ds_cstr(&reply)); + ds_destroy(&reply); +} - unixctl_command_register("inc-engine/show-stats", "", 0, 0, +void +engine_init_global(void) +{ + unixctl_command_register("inc-engine/show-stats", "[engine]", 0, 1, engine_dump_stats, NULL); - unixctl_command_register("inc-engine/clear-stats", "", 0, 0, + unixctl_command_register("inc-engine/clear-stats", "[engine]", 0, 1, engine_clear_stats, NULL); - unixctl_command_register("inc-engine/recompute", "", 0, 0, + unixctl_command_register("inc-engine/recompute", "[engine]", 0, 1, engine_trigger_recompute_cmd, NULL); + unixctl_command_register("inc-engine/list-engines", "", 0, 0, + engine_list_engines, NULL); +} + +struct engine * +engine_new(struct engine_node *node, struct engine_arg *arg, + const char *name) +{ + struct engine *e = xzalloc(sizeof *e); + + e->engine_nodes = engine_get_nodes(node, &e->engine_n_nodes); + e->name = name; + + for (size_t i = 0; i < e->engine_n_nodes; i++) { + if (e->engine_nodes[i]->init) { + e->engine_nodes[i]->data = + e->engine_nodes[i]->init(e->engine_nodes[i], arg); + } else { + e->engine_nodes[i]->data = NULL; + } + e->engine_nodes[i]->e = e; + } + + ovs_list_push_back(&engines, &e->node); + + return e; } void -engine_cleanup(void) +engine_cleanup(struct engine *e) { - for (size_t i = 0; i < engine_n_nodes; i++) { - if (engine_nodes[i]->clear_tracked_data) { - engine_nodes[i]->clear_tracked_data(engine_nodes[i]->data); + for (size_t i = 0; i < e->engine_n_nodes; i++) { + if (e->engine_nodes[i]->clear_tracked_data) { + e->engine_nodes[i]->clear_tracked_data( + e->engine_nodes[i]->data); } - if (engine_nodes[i]->cleanup) { - engine_nodes[i]->cleanup(engine_nodes[i]->data); + if (e->engine_nodes[i]->cleanup) { + e->engine_nodes[i]->cleanup(e->engine_nodes[i]->data); } - free(engine_nodes[i]->data); + free(e->engine_nodes[i]->data); } - free(engine_nodes); - engine_nodes = NULL; - engine_n_nodes = 0; + ovs_list_remove(&e->node); + free(e->engine_nodes); + free(e); } struct engine_node * @@ -284,10 +346,10 @@ engine_node_changed(struct engine_node *node) } bool -engine_has_run(void) +engine_has_run(struct engine *e) { - for (size_t i = 0; i < engine_n_nodes; i++) { - if (engine_nodes[i]->state != EN_STALE) { + for (size_t i = 0; i < e->engine_n_nodes; i++) { + if (e->engine_nodes[i]->state != EN_STALE) { return true; } } @@ -295,9 +357,9 @@ engine_has_run(void) } bool -engine_aborted(void) +engine_aborted(struct engine *e) { - return engine_run_aborted; + return e->engine_run_aborted; } void * @@ -316,14 +378,15 @@ engine_get_internal_data(struct engine_node *node) } void -engine_init_run(void) +engine_init_run(struct engine *e) { VLOG_DBG("Initializing new run"); - for (size_t i = 0; i < engine_n_nodes; i++) { - engine_set_node_state(engine_nodes[i], EN_STALE); + for (size_t i = 0; i < e->engine_n_nodes; i++) { + engine_set_node_state(e->engine_nodes[i], EN_STALE); - if (engine_nodes[i]->clear_tracked_data) { - engine_nodes[i]->clear_tracked_data(engine_nodes[i]->data); + if (e->engine_nodes[i]->clear_tracked_data) { + e->engine_nodes[i]->clear_tracked_data( + e->engine_nodes[i]->data); } } } @@ -397,7 +460,8 @@ engine_compute(struct engine_node *node, bool recompute_allowed) } static void -engine_run_node(struct engine_node *node, bool recompute_allowed) +engine_run_node(struct engine *e, struct engine_node *node, + bool recompute_allowed) { if (!node->n_inputs) { /* Run the node handler which might change state. */ @@ -406,7 +470,7 @@ engine_run_node(struct engine_node *node, bool recompute_allowed) return; } - if (engine_force_recompute) { + if (e->engine_force_recompute) { engine_recompute(node, recompute_allowed, "forced"); return; } @@ -447,41 +511,41 @@ engine_run_node(struct engine_node *node, bool recompute_allowed) } void -engine_run(bool recompute_allowed) +engine_run(struct engine *e, bool recompute_allowed) { /* If the last run was aborted skip the incremental run because a * recompute is needed first. */ - if (!recompute_allowed && engine_run_aborted) { + if (!recompute_allowed && e->engine_run_aborted) { return; } - engine_run_aborted = false; - for (size_t i = 0; i < engine_n_nodes; i++) { - engine_run_node(engine_nodes[i], recompute_allowed); + e->engine_run_aborted = false; + for (size_t i = 0; i < e->engine_n_nodes; i++) { + engine_run_node(e, e->engine_nodes[i], recompute_allowed); - if (engine_nodes[i]->state == EN_ABORTED) { - engine_nodes[i]->stats.abort++; - engine_run_aborted = true; + if (e->engine_nodes[i]->state == EN_ABORTED) { + e->engine_nodes[i]->stats.abort++; + e->engine_run_aborted = true; return; } } } bool -engine_need_run(void) +engine_need_run(struct engine *e) { - for (size_t i = 0; i < engine_n_nodes; i++) { + for (size_t i = 0; i < e->engine_n_nodes; i++) { /* Check only leaf nodes for updates. */ - if (engine_nodes[i]->n_inputs) { + if (e->engine_nodes[i]->n_inputs) { continue; } - engine_nodes[i]->run(engine_nodes[i], engine_nodes[i]->data); - engine_nodes[i]->stats.recompute++; - VLOG_DBG("input node: %s, state: %s", engine_nodes[i]->name, - engine_node_state_name[engine_nodes[i]->state]); - if (engine_nodes[i]->state == EN_UPDATED) { + e->engine_nodes[i]->run(e->engine_nodes[i], e->engine_nodes[i]->data); + e->engine_nodes[i]->stats.recompute++; + VLOG_DBG("input node: %s, state: %s", e->engine_nodes[i]->name, + engine_node_state_name[e->engine_nodes[i]->state]); + if (e->engine_nodes[i]->state == EN_UPDATED) { return true; } } @@ -489,9 +553,9 @@ engine_need_run(void) } void -engine_trigger_recompute(void) +engine_trigger_recompute(struct engine *e) { VLOG_INFO("User triggered force recompute."); - engine_set_force_recompute(true); + engine_set_force_recompute(e, true); poll_immediate_wake(); } diff --git a/lib/inc-proc-eng.h b/lib/inc-proc-eng.h index 9bfab1f7c..881242138 100644 --- a/lib/inc-proc-eng.h +++ b/lib/inc-proc-eng.h @@ -67,6 +67,7 @@ #include #include "compiler.h" +#include "openvswitch/list.h" struct engine_context { struct ovsdb_idl_txn *ovs_idl_txn; @@ -122,6 +123,8 @@ struct engine_stats { }; struct engine_node { + struct engine *e; + /* A unique name for each node. */ char *name; @@ -173,30 +176,47 @@ struct engine_node { struct engine_stats stats; }; +struct engine { + struct ovs_list node; + + const char *name; + + struct engine_node **engine_nodes; + size_t engine_n_nodes; + + bool engine_force_recompute; + bool engine_run_aborted; + + const struct engine_context *engine_context; +}; + +void engine_init_global(void); + /* Initialize the data for the engine nodes. It calls each node's * init() method if not NULL passing the user supplied 'arg'. * It should be called before the main loop. */ -void engine_init(struct engine_node *node, struct engine_arg *arg); +struct engine *engine_new(struct engine_node *node, struct engine_arg *arg, + const char *name); /* Initialize the engine nodes for a new run. It should be called in the * main processing loop before every potential engine_run(). */ -void engine_init_run(void); +void engine_init_run(struct engine *e); /* Execute the processing, which should be called in the main loop. * Updates the engine node's states accordingly. If 'recompute_allowed' is * false and a recompute is required by the current engine run then the engine * aborts. */ -void engine_run(bool recompute_allowed); +void engine_run(struct engine *e, bool recompute_allowed); /* Clean up the data for the engine nodes. It calls each node's * cleanup() method if not NULL. It should be called before the program * terminates. */ -void engine_cleanup(void); +void engine_cleanup(struct engine *e); /* Check if engine needs to run but didn't. */ -bool engine_need_run(void); +bool engine_need_run(struct engine *e); /* Get the input node with for */ struct engine_node * engine_get_input(const char *input_name, @@ -216,7 +236,7 @@ void engine_add_input(struct engine_node *node, struct engine_node *input, * 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); +void engine_set_force_recompute(struct engine *e, bool val); /* Return the current engine_context. The values in the context can be NULL * if the engine is run with allow_recompute == false in the current @@ -224,9 +244,9 @@ void engine_set_force_recompute(bool val); * Therefore, it is the responsibility of the caller to check the context * values when called from change handlers. */ -const struct engine_context *engine_get_context(void); +const struct engine_context *engine_get_context(struct engine *e); -void engine_set_context(const struct engine_context *); +void engine_set_context(struct engine *e, const struct engine_context *); void engine_set_node_state_at(struct engine_node *node, enum engine_node_state state, @@ -236,10 +256,10 @@ void engine_set_node_state_at(struct engine_node *node, bool engine_node_changed(struct engine_node *node); /* Return true if the engine has run in the last iteration. */ -bool engine_has_run(void); +bool engine_has_run(struct engine *e); /* Returns true if during the last engine run we had to abort processing. */ -bool engine_aborted(void); +bool engine_aborted(struct engine *e); /* Return a pointer to node data accessible for users outside the processing * engine. If the node data is not valid (e.g., last engine_run() failed or @@ -265,7 +285,7 @@ void *engine_get_internal_data(struct engine_node *node); engine_set_node_state_at(node, state, OVS_SOURCE_LOCATOR) /* Trigger a full recompute. */ -void engine_trigger_recompute(void); +void engine_trigger_recompute(struct engine *e); struct ed_ovsdb_index { const char *name; diff --git a/northd/en-lflow.c b/northd/en-lflow.c index ffbdaf4e8..5451e0551 100644 --- a/northd/en-lflow.c +++ b/northd/en-lflow.c @@ -32,7 +32,7 @@ VLOG_DEFINE_THIS_MODULE(en_lflow); void en_lflow_run(struct engine_node *node, void *data OVS_UNUSED) { - const struct engine_context *eng_ctx = engine_get_context(); + const struct engine_context *eng_ctx = engine_get_context(node->e); struct lflow_input lflow_input; diff --git a/northd/en-northd.c b/northd/en-northd.c index 79da7e1c4..064f9d93a 100644 --- a/northd/en-northd.c +++ b/northd/en-northd.c @@ -32,7 +32,7 @@ VLOG_DEFINE_THIS_MODULE(en_northd); void en_northd_run(struct engine_node *node, void *data) { - const struct engine_context *eng_ctx = engine_get_context(); + const struct engine_context *eng_ctx = engine_get_context(node->e); struct northd_input input_data; diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c index af55221e3..049fe226a 100644 --- a/northd/inc-proc-northd.c +++ b/northd/inc-proc-northd.c @@ -33,6 +33,8 @@ VLOG_DEFINE_THIS_MODULE(inc_proc_northd); +static struct engine *flow_engine; + #define NB_NODES \ NB_NODE(nb_global, "nb_global") \ NB_NODE(copp, "copp") \ @@ -150,6 +152,8 @@ static ENGINE_NODE(lflow, "lflow"); void inc_proc_northd_init(struct ovsdb_idl_loop *nb, struct ovsdb_idl_loop *sb) { + engine_init_global(); + /* Define relationships between nodes where first argument is dependent * on the second argument */ engine_add_input(&en_northd, &en_nb_nb_global, NULL); @@ -229,7 +233,7 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb, struct ovsdb_idl_index *sbrec_chassis_by_hostname = chassis_hostname_index_create(sb->idl); - engine_init(&en_lflow, &engine_arg); + flow_engine = engine_new(&en_lflow, &engine_arg, "flow_engine"); engine_ovsdb_node_add_index(&en_sb_chassis, "sbrec_chassis_by_name", @@ -251,14 +255,14 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb, void inc_proc_northd_run(struct ovsdb_idl_txn *ovnnb_txn, struct ovsdb_idl_txn *ovnsb_txn, bool recompute) { - engine_init_run(); + engine_init_run(flow_engine); /* Force a full recompute if instructed to, for example, after a NB/SB * reconnect event. However, make sure we don't overwrite an existing * force-recompute request if 'recompute' is false. */ if (recompute) { - engine_set_force_recompute(recompute); + engine_set_force_recompute(flow_engine, recompute); } struct engine_context eng_ctx = { @@ -266,31 +270,31 @@ void inc_proc_northd_run(struct ovsdb_idl_txn *ovnnb_txn, .ovnsb_idl_txn = ovnsb_txn, }; - engine_set_context(&eng_ctx); + engine_set_context(flow_engine, &eng_ctx); if (ovnnb_txn && ovnsb_txn) { - engine_run(true); + engine_run(flow_engine, true); } - if (!engine_has_run()) { - if (engine_need_run()) { + if (!engine_has_run(flow_engine)) { + if (engine_need_run(flow_engine)) { VLOG_DBG("engine did not run, force recompute next time."); - engine_set_force_recompute(true); + engine_set_force_recompute(flow_engine, true); poll_immediate_wake(); } else { VLOG_DBG("engine did not run, and it was not needed"); } - } else if (engine_aborted()) { + } else if (engine_aborted(flow_engine)) { VLOG_DBG("engine was aborted, force recompute next time."); - engine_set_force_recompute(true); + engine_set_force_recompute(flow_engine, true); poll_immediate_wake(); } else { - engine_set_force_recompute(false); + engine_set_force_recompute(flow_engine, false); } } void inc_proc_northd_cleanup(void) { - engine_cleanup(); - engine_set_context(NULL); + engine_set_context(flow_engine, NULL); + engine_cleanup(flow_engine); } From patchwork Fri Jan 14 18:01:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 1580225 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=RC5hTZTr; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4Jb8J21mnBz9ssD for ; Sat, 15 Jan 2022 05:01:38 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 5C7C441627; Fri, 14 Jan 2022 18:01:35 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id VzqURg1HrLFC; Fri, 14 Jan 2022 18:01:34 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp4.osuosl.org (Postfix) with ESMTPS id 63BA641572; Fri, 14 Jan 2022 18:01:33 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 60598C0072; Fri, 14 Jan 2022 18:01:32 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 6F293C0031 for ; Fri, 14 Jan 2022 18:01:30 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 1EF8B60AC3 for ; Fri, 14 Jan 2022 18:01:30 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Authentication-Results: smtp3.osuosl.org (amavisd-new); dkim=pass (1024-bit key) header.d=redhat.com Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id HN3iHqNCg98s for ; Fri, 14 Jan 2022 18:01:29 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by smtp3.osuosl.org (Postfix) with ESMTPS id 4540060ABE for ; Fri, 14 Jan 2022 18:01:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1642183288; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Bx3k9gUbiQc24CQDZzIi6cVd8ocqftBDYDTbkLXCv5A=; b=RC5hTZTrcv09kwgpV6+UvNo3e9flfIwYdUFIyb91fYQBs7+QxxWtzBbVbjCZypUMWEhtCj Ox3qpbnRAHG2qRcZO3F2ibMVua1moDk7uDHsweDFh2UYkGFsBwNaUcMpW2kiev1Xt1Upef 9B21vMpfjv2dBpGKniJgOX3RpiwkgXA= Received: from mail-qk1-f200.google.com (mail-qk1-f200.google.com [209.85.222.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-377-TTkMS6ezO5Kmn7rko6eq8A-1; Fri, 14 Jan 2022 13:01:27 -0500 X-MC-Unique: TTkMS6ezO5Kmn7rko6eq8A-1 Received: by mail-qk1-f200.google.com with SMTP id p68-20020a37a647000000b0047876d0c485so7914463qke.22 for ; Fri, 14 Jan 2022 10:01:26 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Bx3k9gUbiQc24CQDZzIi6cVd8ocqftBDYDTbkLXCv5A=; b=gYkkL/gBEc/1z5KYs+cLOssztihRvsLwP5Oc+h4beb0EuGjLI6EL1tnNikxLkrB4nI jshcvnQSPVY5220cyj8ckaaMAEIGFGBEecbX3NeQdCNhbHxwU6lp6r6MModC+cWh2zKK kcXK/OnNJWGt0oQqSFvxMWJ/gbLFBSNHYoeyepP/PLnDKIpJQCnUV62KZ/MTa+Qfu54+ /WBU72tOlYRYB55ylXYBucjVI5aQ8px7uUS7BMPdRmhX/obaEHAtNk/6XWY+3qMHPjHa v08zeGrhZKJ4C6OBby8o5gfZm0RRAxZ0W19Nb/RLNCAxLWxiekj7gN5vZMWlWNdmnh+W CgGg== X-Gm-Message-State: AOAM5333Qjew1aaVUU5HCk6uWggR7zhfTIs5g9+ygo9hDyL0aFowfZpA j92XoFuLlrrJXT/7lE4sI8mP/h5DC4Md90HXbio+Bm18sbYbjrCZCUS8HOB/h+03hb3375soVJT Vi/7vsJvjMSubst8UD1KOUvZdGNqDPQ3c9+SBksSu5tfmdlEDPSI6pjhnrV2uN5qyTN1Y/sjSxv 7llMM9 X-Received: by 2002:a37:6354:: with SMTP id x81mr7357818qkb.499.1642183286112; Fri, 14 Jan 2022 10:01:26 -0800 (PST) X-Google-Smtp-Source: ABdhPJwhfBC3bCgu9g3Emifu58Ahy4fFxrXt43y4UAUdj/YBPdZqLKU6lKAtTrhLoAmB4IgZRcBQXQ== X-Received: by 2002:a37:6354:: with SMTP id x81mr7357773qkb.499.1642183285644; Fri, 14 Jan 2022 10:01:25 -0800 (PST) Received: from lore-desk.redhat.com (net-93-146-37-237.cust.vodafonedsl.it. [93.146.37.237]) by smtp.gmail.com with ESMTPSA id b6sm4165824qtk.91.2022.01.14.10.01.24 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jan 2022 10:01:25 -0800 (PST) From: Lorenzo Bianconi To: ovs-dev@openvswitch.org Date: Fri, 14 Jan 2022 19:01:18 +0100 Message-Id: <1212633d1a3d342e087416bd9f93b0cef572e011.1642182763.git.lorenzo.bianconi@redhat.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=lorenzo.bianconi@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH v2 ovn 2/3] lib: extend-table: add pending_id map X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Introduce pending_id map used to store meter_id allocated but not yet inserted in the desired_table. This is a preliminary patch to add metering IP engine. Signed-off-by: Lorenzo Bianconi --- controller/ofctrl.c | 9 +++++ controller/ofctrl.h | 1 + lib/extend-table.c | 82 +++++++++++++++++++++++++++++++++------------ lib/extend-table.h | 7 ++++ 4 files changed, 78 insertions(+), 21 deletions(-) diff --git a/controller/ofctrl.c b/controller/ofctrl.c index 08fcfed8b..bf715787e 100644 --- a/controller/ofctrl.c +++ b/controller/ofctrl.c @@ -1801,6 +1801,15 @@ add_meter_string(struct ovn_extend_table_info *m_desired, free(meter_string); } +uint32_t ofctrl_get_meter_id(const char *name, bool new_id) +{ + uint32_t id; + bool val; + + ovn_extend_table_get_id(meters, name, &id, NULL, &val, new_id); + return id; +} + static void add_meter(struct ovn_extend_table_info *m_desired, const struct sbrec_meter_table *meter_table, diff --git a/controller/ofctrl.h b/controller/ofctrl.h index 014de210d..0efcb2ef5 100644 --- a/controller/ofctrl.h +++ b/controller/ofctrl.h @@ -129,5 +129,6 @@ void ofctrl_check_and_add_flow_metered(struct ovn_desired_flow_table *, bool ofctrl_is_connected(void); void ofctrl_set_probe_interval(int probe_interval); void ofctrl_get_memory_usage(struct simap *usage); +uint32_t ofctrl_get_meter_id(const char *name, bool new_id); #endif /* controller/ofctrl.h */ diff --git a/lib/extend-table.c b/lib/extend-table.c index c708e24b9..52c8cd62e 100644 --- a/lib/extend-table.c +++ b/lib/extend-table.c @@ -37,6 +37,7 @@ ovn_extend_table_init(struct ovn_extend_table *table) hmap_init(&table->desired); hmap_init(&table->lflow_to_desired); hmap_init(&table->existing); + shash_init(&table->pending_ids); } static struct ovn_extend_table_info * @@ -191,6 +192,14 @@ ovn_extend_table_clear(struct ovn_extend_table *table, bool existing) } ovn_extend_table_info_destroy(g); } + + struct shash_node *node, *tmp; + SHASH_FOR_EACH_SAFE (node, tmp, &table->pending_ids) { + uint32_t *id = node->data; + shash_delete(&table->pending_ids, node); + free(id); + } + shash_destroy(&table->pending_ids); } void @@ -282,54 +291,85 @@ ovn_extend_table_sync(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, const char *name, - struct uuid lflow_uuid) +bool +ovn_extend_table_get_id(struct ovn_extend_table *table, const char *name, + uint32_t *meter_id, struct uuid *lflow_uuid, + bool *new_id, bool pending) { - uint32_t table_id = 0, hash; struct ovn_extend_table_info *table_info; - - hash = hash_string(name, 0); + uint32_t hash = hash_string(name, 0); /* Check whether we have non installed but allocated group_id. */ HMAP_FOR_EACH_WITH_HASH (table_info, hmap_node, hash, &table->desired) { if (!strcmp(table_info->name, name)) { VLOG_DBG("ovn_externd_table_assign_id: reuse old id %"PRIu32 - " for %s, used by lflow "UUID_FMT, - table_info->table_id, table_info->name, - UUID_ARGS(&lflow_uuid)); - ovn_extend_info_add_lflow_ref(table, table_info, &lflow_uuid); - return table_info->table_id; + " for %s", table_info->table_id, table_info->name); + if (lflow_uuid) { + ovn_extend_info_add_lflow_ref(table, table_info, lflow_uuid); + } + *meter_id = table_info->table_id; + return false; } } + *new_id = false; /* Check whether we already have an installed entry for this * combination. */ HMAP_FOR_EACH_WITH_HASH (table_info, hmap_node, hash, &table->existing) { if (!strcmp(table_info->name, name)) { - table_id = table_info->table_id; + *meter_id = table_info->table_id; + return true; } } - bool new_table_id = false; - if (!table_id) { - /* Reserve a new group_id. */ - table_id = bitmap_scan(table->table_ids, 0, 1, MAX_EXT_TABLE_ID + 1); - new_table_id = true; + /* Check if a ids has been already allocated for this flow. */ + uint32_t *id = shash_find_and_delete(&table->pending_ids, name); + if (id) { + *meter_id = *id; + free(id); + return true; } + /* Reserve a new group_id. */ + uint32_t table_id = bitmap_scan(table->table_ids, 0, 1, + MAX_EXT_TABLE_ID + 1); if (table_id == MAX_EXT_TABLE_ID + 1) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); VLOG_ERR_RL(&rl, "%"PRIu32" out of table ids.", table_id); - return EXT_TABLE_ID_INVALID; + *meter_id = EXT_TABLE_ID_INVALID; + return false; } bitmap_set1(table->table_ids, table_id); + *meter_id = table_id; + + *new_id = true; + if (pending) { + /* Add the id to pedning map. */ + id = xmalloc(sizeof *id); + *id = table_id; + shash_add(&table->pending_ids, name, id); + } + + return true; +} + +/* 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, const char *name, + struct uuid lflow_uuid) +{ + uint32_t table_id, hash = hash_string(name, 0); + struct ovn_extend_table_info *table_info; + bool new_table_id; + + if (!ovn_extend_table_get_id(table, name, &table_id, + &lflow_uuid, &new_table_id, false)) { + return table_id; + } table_info = ovn_extend_table_info_alloc(name, table_id, new_table_id, hash); - hmap_insert(&table->desired, &table_info->hmap_node, table_info->hmap_node.hash); diff --git a/lib/extend-table.h b/lib/extend-table.h index 4d80cfd80..5c5f65695 100644 --- a/lib/extend-table.h +++ b/lib/extend-table.h @@ -21,6 +21,7 @@ #define EXT_TABLE_ID_INVALID 0 #include "openvswitch/hmap.h" +#include "openvswitch/shash.h" #include "openvswitch/list.h" #include "openvswitch/uuid.h" @@ -30,6 +31,8 @@ struct ovn_extend_table { unsigned long *table_ids; /* Used as a bitmap with value set * for allocated group ids in either * desired or existing. */ + struct shash pending_ids; + struct hmap desired; struct hmap lflow_to_desired; /* Index for looking up desired table * items from given lflow uuid, with @@ -93,6 +96,10 @@ void ovn_extend_table_sync(struct ovn_extend_table *); uint32_t ovn_extend_table_assign_id(struct ovn_extend_table *, const char *name, struct uuid lflow_uuid); +bool +ovn_extend_table_get_id(struct ovn_extend_table *table, const char *name, + uint32_t *meter_id, struct uuid *lflow_uuid, + bool *new_id, bool pending); /* 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 Jan 14 18:01:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 1580227 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=OLwTJwfD; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4Jb8JC3S3xz9ssD for ; Sat, 15 Jan 2022 05:01:47 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id E1B34813A4; Fri, 14 Jan 2022 18:01:43 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id cfpUfJLRzpjU; Fri, 14 Jan 2022 18:01:42 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp1.osuosl.org (Postfix) with ESMTPS id 7919783E3D; Fri, 14 Jan 2022 18:01:40 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 34D03C001E; Fri, 14 Jan 2022 18:01:40 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 36F5AC002F for ; Fri, 14 Jan 2022 18:01:38 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 293F083459 for ; Fri, 14 Jan 2022 18:01:37 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 4FS4bR7v_9E5 for ; Fri, 14 Jan 2022 18:01:35 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by smtp1.osuosl.org (Postfix) with ESMTPS id C1BD281372 for ; Fri, 14 Jan 2022 18:01:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1642183293; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=dLFk6FGteGtuATvowjkdtmiOQn7YtB7frA2FBBWFvrI=; b=OLwTJwfD7WcuHPariPOmeYHWqSxMmNDk/C+WlkSkRbZuOPxJ8IVOcRHUgfjelcgoybn2RU pZghyhwTsf4u+C425Om265oORnJBZt9suRD/wrfwjWPpbGC/JBJed5qnAmD+uNHHflDH73 CbZJGZaYo0c9Y5wFBH7QmGtcFk+ypvk= Received: from mail-qk1-f198.google.com (mail-qk1-f198.google.com [209.85.222.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-411-yOllC7oUPzSgBUduqSPCSA-1; Fri, 14 Jan 2022 13:01:31 -0500 X-MC-Unique: yOllC7oUPzSgBUduqSPCSA-1 Received: by mail-qk1-f198.google.com with SMTP id b185-20020a37b2c2000000b004783172e402so7966910qkf.5 for ; Fri, 14 Jan 2022 10:01:31 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=dLFk6FGteGtuATvowjkdtmiOQn7YtB7frA2FBBWFvrI=; b=t+cPqiSsP42EIPbwQS5cuInhxnbHhWe9b9h4ugTmLfJuFa4SDoblBOr8tFmimLDQoY 0N7rPE9dnVBzrxa9Dou+FwjBYMMH+5tIC1sN5YrfnSYWaX7qS1vefjDwthgHYzvCMP3D w2NIAXw5cOOrADjMgVWgODGvJpYrw3fxtwVM71zZgLDTPkbYf/ZpFRGj++8XMepHIjj5 a2pOKrjay1EGborDwvpRzWFLX1HhDhPcfg1FMQ5uctXRn+Rdn4hhrPdAUWonZmad9wbm ibE+wM21L3UJvebVgbk9Sgp8zggNR8AtfuHLRcTTwkufZRLogWschXe1CSbvNIcLe1vC Q9xw== X-Gm-Message-State: AOAM531Xl/Tn2Ej2pDio8QXWO7DxaA0kz58MAzl3IRGEL/zqRloRT2CS hHse0wmomFCwuYjbU5DeHSNLBCTvd8P1S8Y8EfEKzX29l7BnuP/OqmTWrqgRphJJGSMPDWzToOp QAmYSeHnzHJ9vC9fpJVr6ho2Tf01pxvBMp7zg99b/zVBOs/TxWmA2hDIVUxiblNqrTkTASxGfjq lek0/X X-Received: by 2002:a05:6214:e4a:: with SMTP id o10mr8978358qvc.99.1642183287312; Fri, 14 Jan 2022 10:01:27 -0800 (PST) X-Google-Smtp-Source: ABdhPJwaFpjgt5yauJ6xBQF1/+i7bHVzoYQaGB9xTl3RO7jeycLTnTL6ayGQBFHDUgLoYVBM2csQ7A== X-Received: by 2002:a05:6214:e4a:: with SMTP id o10mr8978271qvc.99.1642183286548; Fri, 14 Jan 2022 10:01:26 -0800 (PST) Received: from lore-desk.redhat.com (net-93-146-37-237.cust.vodafonedsl.it. [93.146.37.237]) by smtp.gmail.com with ESMTPSA id b6sm4165824qtk.91.2022.01.14.10.01.25 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jan 2022 10:01:26 -0800 (PST) From: Lorenzo Bianconi To: ovs-dev@openvswitch.org Date: Fri, 14 Jan 2022 19:01:19 +0100 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=lorenzo.bianconi@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH v2 ovn 3/3] controller: reconfigure ovs meters for ovn meters updates X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" At the moment ovs meters are reconfigured by ovn just when a new a meter is allocated while updates for an already allocated meter are ignored. This issue can be easily verified with the following reproducer: $ovn-nbctl meter-add meter0 drop 10 pktps $ovn-nbctl --log --meter=meter0 acl-add sw0 to-lport 1000 'tcp.dst == 80' drop $ovn-nbctl --may-exist meter-add meter0 drop 20 pktps $ovs-ofctl -O OpenFlow15 dump-meters br-int Fix the issue reconfiguring ovs meters even for ovn meters updates. Related bz: https://bugzilla.redhat.com/show_bug.cgi?id=1939524 Signed-off-by: Lorenzo Bianconi --- controller/ofctrl.c | 77 ++++++++++++++++++++++--------------- controller/ofctrl.h | 4 +- controller/ovn-controller.c | 72 +++++++++++++++++++++++++++++++++- tests/ovn.at | 53 ++++++++++++++++++++++++- tests/system-ovn.at | 17 ++++++++ 5 files changed, 188 insertions(+), 35 deletions(-) diff --git a/controller/ofctrl.c b/controller/ofctrl.c index bf715787e..14ca08e94 100644 --- a/controller/ofctrl.c +++ b/controller/ofctrl.c @@ -1810,40 +1810,26 @@ uint32_t ofctrl_get_meter_id(const char *name, bool new_id) return id; } -static void -add_meter(struct ovn_extend_table_info *m_desired, - const struct sbrec_meter_table *meter_table, - struct ovs_list *msgs) +void +set_meter(const struct sbrec_meter *meter, uint32_t id, int cmd) { - const struct sbrec_meter *sb_meter; - SBREC_METER_TABLE_FOR_EACH (sb_meter, meter_table) { - if (!strcmp(m_desired->name, sb_meter->name)) { - break; - } - } - - if (!sb_meter) { - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); - VLOG_ERR_RL(&rl, "could not find meter named \"%s\"", m_desired->name); - return; - } - - struct ofputil_meter_mod mm; - mm.command = OFPMC13_ADD; - mm.meter.meter_id = m_desired->table_id; - mm.meter.flags = OFPMF13_STATS; + struct ovs_list msgs = OVS_LIST_INITIALIZER(&msgs); + struct ofputil_meter_mod mm = { + .command = cmd, + .meter.meter_id = id, + .meter.flags = OFPMF13_STATS, + }; - if (!strcmp(sb_meter->unit, "pktps")) { + if (!strcmp(meter->unit, "pktps")) { mm.meter.flags |= OFPMF13_PKTPS; } else { mm.meter.flags |= OFPMF13_KBPS; } - - mm.meter.n_bands = sb_meter->n_bands; + mm.meter.n_bands = meter->n_bands; mm.meter.bands = xcalloc(mm.meter.n_bands, sizeof *mm.meter.bands); - for (size_t i = 0; i < sb_meter->n_bands; i++) { - struct sbrec_meter_band *sb_band = sb_meter->bands[i]; + for (size_t i = 0; i < meter->n_bands; i++) { + struct sbrec_meter_band *sb_band = meter->bands[i]; struct ofputil_meter_band *mm_band = &mm.meter.bands[i]; if (!strcmp(sb_band->action, "drop")) { @@ -1858,9 +1844,41 @@ add_meter(struct ovn_extend_table_info *m_desired, mm.meter.flags |= OFPMF13_BURST; } } - - add_meter_mod(&mm, msgs); + add_meter_mod(&mm, &msgs); free(mm.meter.bands); + + if (!ovs_list_is_empty(&msgs)) { + /* Add a barrier to the list of messages. */ + struct ofpbuf *barrier = ofputil_encode_barrier_request(OFP15_VERSION); + + ovs_list_push_back(&msgs, &barrier->list_node); + /* Queue the messages. */ + struct ofpbuf *msg; + LIST_FOR_EACH_POP (msg, list_node, &msgs) { + queue_msg(msg); + } + } +} + +void +remove_meter(uint32_t id) +{ + struct ovs_list msgs = OVS_LIST_INITIALIZER(&msgs); + /* Delete the meter. */ + struct ofputil_meter_mod mm = { + .command = OFPMC13_DELETE, + .meter = { .meter_id = id }, + }; + add_meter_mod(&mm, &msgs); + /* Add a barrier to the list of messages. */ + struct ofpbuf *barrier = ofputil_encode_barrier_request(OFP15_VERSION); + + ovs_list_push_back(&msgs, &barrier->list_node); + /* Queue the messages. */ + struct ofpbuf *msg; + LIST_FOR_EACH_POP (msg, list_node, &msgs) { + queue_msg(msg); + } } static void @@ -2161,7 +2179,6 @@ void ofctrl_put(struct ovn_desired_flow_table *lflow_table, struct ovn_desired_flow_table *pflow_table, struct shash *pending_ct_zones, - const struct sbrec_meter_table *meter_table, uint64_t req_cfg, bool lflows_changed, bool pflows_changed) @@ -2246,8 +2263,6 @@ ofctrl_put(struct ovn_desired_flow_table *lflow_table, /* The "set-meter" action creates a meter entry name that * describes the meter itself. */ add_meter_string(m_desired, &msgs); - } else { - add_meter(m_desired, meter_table, &msgs); } } diff --git a/controller/ofctrl.h b/controller/ofctrl.h index 0efcb2ef5..53af92cfb 100644 --- a/controller/ofctrl.h +++ b/controller/ofctrl.h @@ -29,6 +29,7 @@ struct match; struct ofpbuf; struct ovsrec_bridge; struct sbrec_meter_table; +struct sbrec_meter; struct shash; struct ovn_desired_flow_table { @@ -55,7 +56,6 @@ enum mf_field_id ofctrl_get_mf_field_id(void); void ofctrl_put(struct ovn_desired_flow_table *lflow_table, struct ovn_desired_flow_table *pflow_table, struct shash *pending_ct_zones, - const struct sbrec_meter_table *, uint64_t nb_cfg, bool lflow_changed, bool pflow_changed); @@ -130,5 +130,7 @@ bool ofctrl_is_connected(void); void ofctrl_set_probe_interval(int probe_interval); void ofctrl_get_memory_usage(struct simap *usage); uint32_t ofctrl_get_meter_id(const char *name, bool new_id); +void set_meter(const struct sbrec_meter *meter, uint32_t id, int cmd); +void remove_meter(uint32_t id); #endif /* controller/ofctrl.h */ diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c index 86cb6f769..ac332ff94 100644 --- a/controller/ovn-controller.c +++ b/controller/ovn-controller.c @@ -76,6 +76,7 @@ #include "stopwatch.h" #include "lib/inc-proc-eng.h" #include "hmapx.h" +#include "openvswitch/ofp-util.h" VLOG_DEFINE_THIS_MODULE(main); @@ -115,6 +116,7 @@ static unixctl_cb_func debug_delay_nb_cfg_report; #define OVS_STARTUP_TS_NAME "ovn-startup-ts" static struct engine *flow_engine; +static struct engine *meter_engine; static char *parse_options(int argc, char *argv[]); OVS_NO_RETURN static void usage(void); @@ -964,7 +966,8 @@ ctrl_register_ovs_idl(struct ovsdb_idl *ovs_idl) SB_NODE(dhcpv6_options, "dhcpv6_options") \ SB_NODE(dns, "dns") \ SB_NODE(load_balancer, "load_balancer") \ - SB_NODE(fdb, "fdb") + SB_NODE(fdb, "fdb") \ + SB_NODE(meter, "meter") enum sb_engine_node { #define SB_NODE(NAME, NAME_STR) SB_##NAME, @@ -1509,6 +1512,65 @@ addr_sets_sb_address_set_handler(struct engine_node *node, void *data) return true; } +struct ed_type_meter { + bool change_tracked; +}; + +static void * +en_meter_init(struct engine_node *node OVS_UNUSED, + struct engine_arg *arg OVS_UNUSED) +{ + struct ed_type_meter *m = xzalloc(sizeof *m); + + m->change_tracked = false; + return m; +} + +static void +en_meter_cleanup(void *data OVS_UNUSED) +{ +} + +static void +en_meter_run(struct engine_node *node, void *data) +{ + struct ed_type_meter *m = data; + + engine_set_node_state(node, EN_UPDATED); + m->change_tracked = false; +} + +static bool +meter_sb_meter_handler(struct engine_node *node, void *data) +{ + struct ovs_list msgs = OVS_LIST_INITIALIZER(&msgs); + struct ed_type_meter *m = data; + + struct sbrec_meter_table *m_table = + (struct sbrec_meter_table *)EN_OVSDB_GET( + engine_get_input("SB_meter", node)); + + uint32_t id; + const struct sbrec_meter *iter; + SBREC_METER_TABLE_FOR_EACH_TRACKED (iter, m_table) { + id = ofctrl_get_meter_id(iter->name, !sbrec_meter_is_deleted(iter)); + if (id == EXT_TABLE_ID_INVALID) { + return false; + } + + if (sbrec_meter_is_deleted(iter)) { + remove_meter(id); + } else { + int cmd = sbrec_meter_is_new(iter) ? OFPMC13_ADD : OFPMC13_MODIFY; + + set_meter(iter, id, cmd); + } + } + m->change_tracked = true; + + return true; +} + struct ed_type_port_groups{ /* A copy of SB port_groups, each converted as a sset for efficient lport * lookup. */ @@ -3223,6 +3285,7 @@ main(int argc, char *argv[]) ENGINE_NODE(lflow_output, "logical_flow_output"); ENGINE_NODE(flow_output, "flow_output"); ENGINE_NODE(addr_sets, "addr_sets"); + ENGINE_NODE(meter, "meter"); ENGINE_NODE_WITH_CLEAR_TRACK_DATA(port_groups, "port_groups"); #define SB_NODE(NAME, NAME_STR) ENGINE_NODE_SB(NAME, NAME_STR); @@ -3347,11 +3410,14 @@ main(int argc, char *argv[]) engine_add_input(&en_flow_output, &en_pflow_output, flow_output_pflow_output_handler); + engine_add_input(&en_meter, &en_sb_meter, meter_sb_meter_handler); + struct engine_arg engine_arg = { .sb_idl = ovnsb_idl_loop.idl, .ovs_idl = ovs_idl_loop.idl, }; flow_engine = engine_new(&en_flow_output, &engine_arg, "flow_engine"); + meter_engine = engine_new(&en_meter, &engine_arg, "meter_engine"); engine_ovsdb_node_add_index(&en_sb_chassis, "name", sbrec_chassis_by_name); engine_ovsdb_node_add_index(&en_sb_multicast_group, "name_datapath", @@ -3488,6 +3554,7 @@ main(int argc, char *argv[]) } engine_init_run(flow_engine); + engine_init_run(meter_engine); struct ovsdb_idl_txn *ovs_idl_txn = ovsdb_idl_loop_run(&ovs_idl_loop); unsigned int new_ovs_cond_seqno @@ -3594,6 +3661,7 @@ main(int argc, char *argv[]) engine_set_force_recompute(flow_engine, true); } + engine_run(meter_engine, true); if (br_int) { ct_zones_data = engine_get_data(&en_ct_zones); if (ct_zones_data) { @@ -3761,7 +3829,6 @@ main(int argc, char *argv[]) ofctrl_put(&lflow_output_data->flow_table, &pflow_output_data->flow_table, &ct_zones_data->pending, - sbrec_meter_table_get(ovnsb_idl_loop.idl), ofctrl_seqno_get_req_cfg(), engine_node_changed(&en_lflow_output), engine_node_changed(&en_pflow_output)); @@ -3905,6 +3972,7 @@ loop_done: engine_set_context(flow_engine, NULL); engine_cleanup(flow_engine); + engine_cleanup(meter_engine); /* It's time to exit. Clean up the databases if we are not restarting */ if (!restart) { diff --git a/tests/ovn.at b/tests/ovn.at index 92e284e8a..9a5e6b196 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -9181,7 +9181,7 @@ ovn-nbctl acl-del lsw0 to-lport 1000 'tcp.dst==80' ovn-nbctl --wait=hv sync AT_CHECK([ovs-ofctl -O OpenFlow13 dump-meters br-int | grep meter], [0], [ignore], [ignore]) -# Delete acl2, meter should be deleted in OVS +# Delete acl2, meter should be kept in OVS ovn-nbctl acl-del lsw0 to-lport 1000 'tcp.dst==81' ovn-nbctl --wait=hv sync AT_CHECK([ovs-ofctl -O OpenFlow13 dump-meters br-int | grep meter], [1]) @@ -29704,3 +29704,54 @@ OVS_WAIT_UNTIL([ OVN_CLEANUP([hv1],[hv2]) AT_CLEANUP ]) + +OVN_FOR_EACH_NORTHD([ +AT_SETUP([ovn-controller - check meters update]) +AT_KEYWORDS([meters-update]) + +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 + +check ovn-nbctl ls-add sw0 +check ovn-nbctl lsp-add sw0 lsp + +as hv1 ovs-vsctl \ + -- add-port br-int vif1 \ + -- set Interface vif1 external_ids:iface-id=lsp + +# Wait for port to be bound. +wait_row_count Chassis 1 name=hv1 +ch=$(fetch_column Chassis _uuid name=hv1) +wait_row_count Port_Binding 1 logical_port=lsp chassis=$ch + +# Add a new meter +check ovn-nbctl meter-add meter0 drop 10 pktps +check ovn-nbctl --log --severity=alert --meter=meter0 --name=http acl-add sw0 \ + to-lport 1000 'tcp.dst == 80' drop +check ovn-nbctl --wait=hv sync + +AT_CHECK([as hv1 ovs-ofctl -OOpenFlow15 dump-meters br-int | grep -q rate=10], [0]) + +# Update existing meter +check ovn-nbctl --may-exist meter-add meter0 drop 20 pktps +check ovn-nbctl --wait=hv sync + +AT_CHECK([as hv1 ovs-ofctl -OOpenFlow15 dump-meters br-int | grep -q rate=20], [0]) + +# Update existing meter and do a full recompute +as hv1 ovn-appctl -t ovn-controller debug/pause +check ovn-nbctl --may-exist meter-add meter0 drop 30 pktps +check ovn-sbctl chassis-add hv2 geneve 127.0.0.1 +check ovn-nbctl --wait=sb sync +as hv1 ovn-appctl -t ovn-controller debug/resume + +AT_CHECK([as hv1 ovs-ofctl -OOpenFlow15 dump-meters br-int | grep -q rate=30], [0]) + +OVN_CLEANUP([hv1]) +AT_CLEANUP +]) diff --git a/tests/system-ovn.at b/tests/system-ovn.at index 7f6cb32dc..80d5192ca 100644 --- a/tests/system-ovn.at +++ b/tests/system-ovn.at @@ -6667,8 +6667,25 @@ OVS_WAIT_UNTIL([ test "${n_reject}" = "2" ]) kill $(pidof tcpdump) +rm -f reject.pcap + +# Let's update the meter +NS_EXEC([sw01], [tcpdump -l -n -i sw01 icmp -Q in > reject.pcap &]) +check ovn-nbctl --may-exist meter-add acl-meter drop 10 pktps 0 +ip netns exec sw01 scapy -H <<-EOF +p = IP(src="192.168.1.2", dst="192.168.1.1") / UDP(dport = 12345) / Raw(b"X"*64) +send (p, iface='sw01', loop = 0, verbose = 0, count = 100) +EOF +# 10pps + 1 burst size +OVS_WAIT_UNTIL([ + n_reject=$(grep unreachable reject.pcap | wc -l) + test "${n_reject}" = "20" +]) + +kill $(pidof tcpdump) rm -f reject.pcap + NS_EXEC([sw01], [tcpdump -l -n -i sw01 icmp -Q in > reject.pcap &]) check ovn-nbctl --wait=hv ls-copp-del sw0 reject