From patchwork Tue Nov 3 22:18:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Flaviof X-Patchwork-Id: 1393500 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=fraxinus.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=flaviof.com Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CQkhS5c1rz9sPB for ; Wed, 4 Nov 2020 09:18:48 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 2BF7986442; Tue, 3 Nov 2020 22:18:47 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id hSnwClA1MlHG; Tue, 3 Nov 2020 22:18:44 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id B5906868A8; Tue, 3 Nov 2020 22:18:44 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id A92AAC0051; Tue, 3 Nov 2020 22:18:44 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id EBD28C0051 for ; Tue, 3 Nov 2020 22:18:43 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id D5D13868BE for ; Tue, 3 Nov 2020 22:18:43 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 31hkdJp6Joi6 for ; Tue, 3 Nov 2020 22:18:41 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail-qk1-f196.google.com (mail-qk1-f196.google.com [209.85.222.196]) by fraxinus.osuosl.org (Postfix) with ESMTPS id 78F75864CD for ; Tue, 3 Nov 2020 22:18:41 +0000 (UTC) Received: by mail-qk1-f196.google.com with SMTP id z6so16904345qkz.4 for ; Tue, 03 Nov 2020 14:18:41 -0800 (PST) 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:senderwebaddress; bh=pKaC3qj+az/Dy8lOhXKqgakAaWljxl3pQJFPNzXetYQ=; b=ABRZUt7yK3KrmugTWRtw9Q3ygt7LsxK7nlAPiMqeNA37RcAgLn6YQCyCflo1yqUvnt qxLaYQeCkT8JTWc6D5Kk2Uoa3IMrt1sE1YwBW3YHmDi2NbqYVsAo8XmFELK6Ou4lbebG MWM0gEp1qsq1UTsVKUIr+Zz8i/ncFjZ3swk4b0o5eQ2tbZHb+ZZUPumghS8eHhC9jCBX d0gOBpqDDt4s0zURERJal+eapWRFSb/VZLr1ZQFGP/1R1u1M1tyOSGcFTov9YFOkgScU Yr5a13llMkEWWW3l5zYVpomO27ZHTVWSddmfHwhYqAllPG676H5M2NnibLBv5pe28UQU YxVg== X-Gm-Message-State: AOAM530DUb6C+p7nh9qNZijCMrJMMION7cTUoGLhMBEYkcnfyYhY4oaN 3bnRnkDxfeoyLpdzziwxBLdcch9zlRqvWA== X-Google-Smtp-Source: ABdhPJzqrz085KHOkyEiKQcmmqn6y6sGqMQtl62NKr5TodBAN/5Rl5vnG7KM7pyKPLjTt0fHvscOWg== X-Received: by 2002:ae9:efd5:: with SMTP id d204mr21348366qkg.158.1604441919925; Tue, 03 Nov 2020 14:18:39 -0800 (PST) Received: from c8vm.redhat.com (pool-173-76-170-96.bstnma.fios.verizon.net. [173.76.170.96]) by smtp.gmail.com with ESMTPSA id k134sm140423qke.111.2020.11.03.14.18.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Nov 2020 14:18:39 -0800 (PST) From: Flavio Fernandes To: dev@openvswitch.org Date: Tue, 3 Nov 2020 22:18:34 +0000 Message-Id: <20201103221834.25541-2-flavio@flaviof.com> X-Mailer: git-send-email 2.18.4 In-Reply-To: <20201103221834.25541-1-flavio@flaviof.com> References: <20201103221834.25541-1-flavio@flaviof.com> SenderWebAddress: http://flaviof.com/ Subject: [ovs-dev] [PATCH v3 ovn 1/1] northd: Enhance the implementation of ACL log meters. 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: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" When multiple ACL rows use the same Meter for log rate-limiting, the 'noisiest' ACL matches may completely consume the Meter and shadow other ACL logs. This patch introduces an option in NB_Global that allows for a Meter to rate-limit each ACL log separately. The change is backward compatible. Based on a well known option, northd will turn a single Meter in the NB into multiple Meters in the SB by appending the ACL uuid to its name. It will also make action in logical flow use the unique Meter name for each affected ACL log. In order to make the Meter behave as described, add this option: ovn-nbctl set nb_global . options:acl_shared_log_meters="${meter_name}" If more than one Meter is wanted, simply use a comma to separate each name. Reported-by: Flavio Fernandes Reported-at: https://mail.openvswitch.org/pipermail/ovs-discuss/2020-October/050769.html Signed-off-by: Flavio Fernandes --- v2 -> v3: * Use recently introduced testing helpers (4afe409e9). v1 -> v2: * Rebase master b38e10f4b. TODO: I do not yet know the implications that this change have on the new ddlog based implementation of northd. Will read up and contact folks on that. northd/ovn-northd.c | 201 ++++++++++++++++++++++++++++++++------------ ovn-nb.xml | 14 +++ tests/ovn-northd.at | 92 ++++++++++++++++++++ 3 files changed, 255 insertions(+), 52 deletions(-) diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index 8800a3d3c..721e7be97 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -5378,8 +5378,53 @@ build_acl_hints(struct ovn_datapath *od, struct hmap *lflows) } } +static bool +is_a_shared_meter(const struct smap *nb_options, const char *meter_name) +{ + bool is_shared_meter = false; + const char *meters = smap_get(nb_options, "acl_shared_log_meters"); + if (meters && meters[0]) { + char *cur, *next, *start; + next = start = xstrdup(meters); + while ((cur = strsep(&next, ",")) && *cur) { + if (!strcmp(meter_name, cur)) { + is_shared_meter = true; + break; + } + } + free(start); + } + return is_shared_meter; +} + +static char* +alloc_acl_log_unique_meter_name(const struct nbrec_acl *acl) +{ + return xasprintf("%s__" UUID_FMT, + acl->meter, UUID_ARGS(&acl->header_.uuid)); +} + +static void +build_acl_log_meter(struct ds *actions, const struct nbrec_acl *acl, + const struct smap *nb_options) +{ + if (!acl->meter) { + return; + } + + /* If ACL log meter uses a shared meter, use unique Meter name. */ + if (is_a_shared_meter(nb_options, acl->meter)) { + char *meter_name = alloc_acl_log_unique_meter_name(acl); + ds_put_format(actions, "meter=\"%s\", ", meter_name); + free(meter_name); + } else { + ds_put_format(actions, "meter=\"%s\", ", acl->meter); + } +} + static void -build_acl_log(struct ds *actions, const struct nbrec_acl *acl) +build_acl_log(struct ds *actions, const struct nbrec_acl *acl, + const struct smap *nb_options) { if (!acl->log) { return; @@ -5407,9 +5452,7 @@ build_acl_log(struct ds *actions, const struct nbrec_acl *acl) ds_put_cstr(actions, "verdict=allow, "); } - if (acl->meter) { - ds_put_format(actions, "meter=\"%s\", ", acl->meter); - } + build_acl_log_meter(actions, acl, nb_options); ds_chomp(actions, ' '); ds_chomp(actions, ','); @@ -5420,7 +5463,8 @@ static void build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows, enum ovn_stage stage, struct nbrec_acl *acl, struct ds *extra_match, struct ds *extra_actions, - const struct ovsdb_idl_row *stage_hint) + const struct ovsdb_idl_row *stage_hint, + const struct smap *nb_options) { struct ds match = DS_EMPTY_INITIALIZER; struct ds actions = DS_EMPTY_INITIALIZER; @@ -5432,7 +5476,7 @@ build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows, ingress ? ovn_stage_get_table(S_SWITCH_OUT_QOS_MARK) : ovn_stage_get_table(S_SWITCH_IN_L2_LKUP)); - build_acl_log(&actions, acl); + build_acl_log(&actions, acl, nb_options); if (extra_match->length > 0) { ds_put_format(&match, "(%s) && ", extra_match->string); } @@ -5457,7 +5501,8 @@ build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows, static void consider_acl(struct hmap *lflows, struct ovn_datapath *od, - struct nbrec_acl *acl, bool has_stateful) + struct nbrec_acl *acl, bool has_stateful, + const struct smap *nb_options) { bool ingress = !strcmp(acl->direction, "from-lport") ? true :false; enum ovn_stage stage = ingress ? S_SWITCH_IN_ACL : S_SWITCH_OUT_ACL; @@ -5471,7 +5516,7 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od, * associated conntrack entry and would return "+invalid". */ if (!has_stateful) { struct ds actions = DS_EMPTY_INITIALIZER; - build_acl_log(&actions, acl); + build_acl_log(&actions, acl, nb_options); ds_put_cstr(&actions, "next;"); ovn_lflow_add_with_hint(lflows, od, stage, acl->priority + OVN_ACL_PRI_OFFSET, @@ -5497,7 +5542,7 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od, ds_put_format(&match, REGBIT_ACL_HINT_ALLOW_NEW " == 1 && (%s)", acl->match); ds_put_cstr(&actions, REGBIT_CONNTRACK_COMMIT" = 1; "); - build_acl_log(&actions, acl); + build_acl_log(&actions, acl, nb_options); ds_put_cstr(&actions, "next;"); ovn_lflow_add_with_hint(lflows, od, stage, acl->priority + OVN_ACL_PRI_OFFSET, @@ -5516,7 +5561,7 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od, ds_put_format(&match, REGBIT_ACL_HINT_ALLOW " == 1 && (%s)", acl->match); - build_acl_log(&actions, acl); + build_acl_log(&actions, acl, nb_options); ds_put_cstr(&actions, "next;"); ovn_lflow_add_with_hint(lflows, od, stage, acl->priority + OVN_ACL_PRI_OFFSET, @@ -5541,10 +5586,10 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od, ds_put_cstr(&match, REGBIT_ACL_HINT_DROP " == 1"); if (!strcmp(acl->action, "reject")) { build_reject_acl_rules(od, lflows, stage, acl, &match, - &actions, &acl->header_); + &actions, &acl->header_, nb_options); } else { ds_put_format(&match, " && (%s)", acl->match); - build_acl_log(&actions, acl); + build_acl_log(&actions, acl, nb_options); ds_put_cstr(&actions, "/* drop */"); ovn_lflow_add_with_hint(lflows, od, stage, acl->priority + OVN_ACL_PRI_OFFSET, @@ -5568,10 +5613,10 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od, ds_put_cstr(&actions, "ct_commit { ct_label.blocked = 1; }; "); if (!strcmp(acl->action, "reject")) { build_reject_acl_rules(od, lflows, stage, acl, &match, - &actions, &acl->header_); + &actions, &acl->header_, nb_options); } else { ds_put_format(&match, " && (%s)", acl->match); - build_acl_log(&actions, acl); + build_acl_log(&actions, acl, nb_options); ds_put_cstr(&actions, "/* drop */"); ovn_lflow_add_with_hint(lflows, od, stage, acl->priority + OVN_ACL_PRI_OFFSET, @@ -5584,9 +5629,9 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od, * logical flow action in all cases. */ if (!strcmp(acl->action, "reject")) { build_reject_acl_rules(od, lflows, stage, acl, &match, - &actions, &acl->header_); + &actions, &acl->header_, nb_options); } else { - build_acl_log(&actions, acl); + build_acl_log(&actions, acl, nb_options); ds_put_cstr(&actions, "/* drop */"); ovn_lflow_add_with_hint(lflows, od, stage, acl->priority + OVN_ACL_PRI_OFFSET, @@ -5666,7 +5711,7 @@ build_port_group_lswitches(struct northd_context *ctx, struct hmap *pgs, static void build_acls(struct ovn_datapath *od, struct hmap *lflows, - struct hmap *port_groups) + struct hmap *port_groups, const struct smap *nb_options) { bool has_stateful = (has_stateful_acl(od) || has_lb_vip(od)); @@ -5769,13 +5814,14 @@ build_acls(struct ovn_datapath *od, struct hmap *lflows, /* Ingress or Egress ACL Table (Various priorities). */ for (size_t i = 0; i < od->nbs->n_acls; i++) { struct nbrec_acl *acl = od->nbs->acls[i]; - consider_acl(lflows, od, acl, has_stateful); + consider_acl(lflows, od, acl, has_stateful, nb_options); } struct ovn_port_group *pg; HMAP_FOR_EACH (pg, key_node, port_groups) { if (ovn_port_group_ls_find(pg, &od->nbs->header_.uuid)) { for (size_t i = 0; i < pg->nb_pg->n_acls; i++) { - consider_acl(lflows, od, pg->nb_pg->acls[i], has_stateful); + consider_acl(lflows, od, pg->nb_pg->acls[i], has_stateful, + nb_options); } } } @@ -6791,7 +6837,7 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports, struct hmap *port_groups, struct hmap *lflows, struct hmap *mcgroups, struct hmap *igmp_groups, struct shash *meter_groups, - struct hmap *lbs) + struct hmap *lbs, const struct smap *nb_options) { /* This flow table structure is documented in ovn-northd(8), so please * update ovn-northd.8.xml if you change anything. */ @@ -6811,7 +6857,7 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports, build_pre_lb(od, lflows, meter_groups, lbs); build_pre_stateful(od, lflows); build_acl_hints(od, lflows); - build_acls(od, lflows, port_groups); + build_acls(od, lflows, port_groups, nb_options); build_qos(od, lflows); build_lb(od, lflows); build_stateful(od, lflows, lbs); @@ -11395,8 +11441,12 @@ build_lflows(struct northd_context *ctx, struct hmap *datapaths, { struct hmap lflows = HMAP_INITIALIZER(&lflows); + const struct nbrec_nb_global *nb_global = + nbrec_nb_global_first(ctx->ovnnb_idl); + ovs_assert(nb_global); + build_lswitch_flows(datapaths, ports, port_groups, &lflows, mcgroups, - igmp_groups, meter_groups, lbs); + igmp_groups, meter_groups, lbs, &nb_global->options); build_lrouter_flows(datapaths, ports, &lflows, meter_groups, lbs); /* Push changes to the Logical_Flow table to database. */ @@ -11740,15 +11790,85 @@ done: return need_update; } +static void +sync_meters_iterate_nb_meter(struct northd_context *ctx, + const char *meter_name, + const struct nbrec_meter *nb_meter, + struct shash *sb_meters) +{ + bool new_sb_meter = false; + + const struct sbrec_meter *sb_meter = shash_find_and_delete(sb_meters, + meter_name); + if (!sb_meter) { + sb_meter = sbrec_meter_insert(ctx->ovnsb_txn); + sbrec_meter_set_name(sb_meter, meter_name); + new_sb_meter = true; + } + + if (new_sb_meter || bands_need_update(nb_meter, sb_meter)) { + struct sbrec_meter_band **sb_bands; + sb_bands = xcalloc(nb_meter->n_bands, sizeof *sb_bands); + for (size_t i = 0; i < nb_meter->n_bands; i++) { + const struct nbrec_meter_band *nb_band = nb_meter->bands[i]; + + sb_bands[i] = sbrec_meter_band_insert(ctx->ovnsb_txn); + + sbrec_meter_band_set_action(sb_bands[i], nb_band->action); + sbrec_meter_band_set_rate(sb_bands[i], nb_band->rate); + sbrec_meter_band_set_burst_size(sb_bands[i], + nb_band->burst_size); + } + sbrec_meter_set_bands(sb_meter, sb_bands, nb_meter->n_bands); + free(sb_bands); + } + + sbrec_meter_set_unit(sb_meter, nb_meter->unit); +} + +static void +sync_acl_shared_meters(struct northd_context *ctx, + struct hmap *datapaths, + const struct smap *nb_options, + const struct nbrec_meter *nb_meter, + struct shash *sb_meters) +{ + if (!is_a_shared_meter(nb_options, nb_meter->name)) { + return; + } + + struct ovn_datapath *od; + HMAP_FOR_EACH (od, key_node, datapaths) { + if (!od->nbs) { + continue; + } + for (size_t i = 0; i < od->nbs->n_acls; i++) { + struct nbrec_acl *acl = od->nbs->acls[i]; + if (!acl->meter || strcmp(nb_meter->name, acl->meter)) { + continue; + } + + char *meter_name = alloc_acl_log_unique_meter_name(acl); + sync_meters_iterate_nb_meter(ctx, meter_name, nb_meter, sb_meters); + free(meter_name); + } + } +} + /* Each entry in the Meter and Meter_Band tables in OVN_Northbound have * a corresponding entries in the Meter and Meter_Band tables in - * OVN_Southbound. + * OVN_Southbound. Additionally, ACL logs that use shared meters have + * a private copy of its meter in the SB table. */ static void -sync_meters(struct northd_context *ctx) +sync_meters(struct northd_context *ctx, struct hmap *datapaths) { struct shash sb_meters = SHASH_INITIALIZER(&sb_meters); + const struct nbrec_nb_global *nb_global = + nbrec_nb_global_first(ctx->ovnnb_idl); + ovs_assert(nb_global); + const struct sbrec_meter *sb_meter; SBREC_METER_FOR_EACH (sb_meter, ctx->ovnsb_idl) { shash_add(&sb_meters, sb_meter->name, sb_meter); @@ -11756,33 +11876,10 @@ sync_meters(struct northd_context *ctx) const struct nbrec_meter *nb_meter; NBREC_METER_FOR_EACH (nb_meter, ctx->ovnnb_idl) { - bool new_sb_meter = false; - - sb_meter = shash_find_and_delete(&sb_meters, nb_meter->name); - if (!sb_meter) { - sb_meter = sbrec_meter_insert(ctx->ovnsb_txn); - sbrec_meter_set_name(sb_meter, nb_meter->name); - new_sb_meter = true; - } - - if (new_sb_meter || bands_need_update(nb_meter, sb_meter)) { - struct sbrec_meter_band **sb_bands; - sb_bands = xcalloc(nb_meter->n_bands, sizeof *sb_bands); - for (size_t i = 0; i < nb_meter->n_bands; i++) { - const struct nbrec_meter_band *nb_band = nb_meter->bands[i]; - - sb_bands[i] = sbrec_meter_band_insert(ctx->ovnsb_txn); - - sbrec_meter_band_set_action(sb_bands[i], nb_band->action); - sbrec_meter_band_set_rate(sb_bands[i], nb_band->rate); - sbrec_meter_band_set_burst_size(sb_bands[i], - nb_band->burst_size); - } - sbrec_meter_set_bands(sb_meter, sb_bands, nb_meter->n_bands); - free(sb_bands); - } - - sbrec_meter_set_unit(sb_meter, nb_meter->unit); + sync_meters_iterate_nb_meter(ctx, nb_meter->name, nb_meter, + &sb_meters); + sync_acl_shared_meters(ctx, datapaths, &nb_global->options, nb_meter, + &sb_meters); } struct shash_node *node, *next; @@ -12271,7 +12368,7 @@ ovnnb_db_run(struct northd_context *ctx, sync_address_sets(ctx); sync_port_groups(ctx, &port_groups); - sync_meters(ctx); + sync_meters(ctx, datapaths); sync_dns_entries(ctx, datapaths); destroy_ovn_lbs(&lbs); hmap_destroy(&lbs); diff --git a/ovn-nb.xml b/ovn-nb.xml index 5e8635992..51b186b84 100644 --- a/ovn-nb.xml +++ b/ovn-nb.xml @@ -193,6 +193,20 @@

+ +

+ A string value that contains a list of meter names delimited by ",". + The column is used by ACL to rate + limit log events. As multiple ACL rows may opt to use the same meter + name, a potentially adverse effect is that a "noisy" ACL log could + consume all the allowable events for the shared + . This global option can be used to + eliminate that behavior, by listing the meters that are meant to + provide its "complete" rate to each one of the + logs that use it. +

+
+

These options control how routes are advertised between OVN diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index ae845e4ea..58fcc1350 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -1781,6 +1781,98 @@ action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implici AT_CLEANUP +AT_SETUP([ovn-northd -- ACL shared Meter]) +AT_KEYWORDS([acl meter]) +ovn_start + +ovn-nbctl ls-add sw0 +ovn-nbctl lsp-add sw0 sw0-p1 -- lsp-set-addresses sw0-p1 "50:54:00:00:00:01 10.0.0.11" +ovn-nbctl lsp-add sw0 sw0-p2 -- lsp-set-addresses sw0-p2 "50:54:00:00:00:02 10.0.0.12" +ovn-nbctl lsp-add sw0 sw0-p3 -- lsp-set-addresses sw0-p3 "50:54:00:00:00:03 10.0.0.13" + +ovn-nbctl remove nb_global . options acl_shared_log_meters +ovn-nbctl meter-add meter_me drop 1 pktps + +ovn-nbctl acl-add sw0 to-lport 1002 'outport == "sw0-p1" && ip4.src == 10.0.0.12' allow +ovn-nbctl acl-add sw0 to-lport 1002 'outport == "sw0-p1" && ip4.src == 10.0.0.13' allow + +acl1=$(ovn-nbctl --bare --column _uuid,match find acl | grep -B1 '10.0.0.12' | head -1) +acl2=$(ovn-nbctl --bare --column _uuid,match find acl | grep -B1 '10.0.0.13' | head -1) +ovn-nbctl set acl $acl1 log=true severity=alert meter=meter_me name=acl_one +ovn-nbctl set acl $acl2 log=true severity=info meter=meter_me name=acl_two +ovn-nbctl --wait=sb sync + +check_row_count nb:meter 1 +check_column meter_me nb:meter name + +check_acl_lflow() { + acl_log_name=$1 + meter_name=$2 + # echo checking that logical flow for acl log $acl_log_name has $meter_name + AT_CHECK([ovn-sbctl lflow-list | grep ls_out_acl | \ + grep "\"${acl_log_name}\"" | \ + grep -c "meter=\"${meter_name}\""], [0], [1 +]) +} + +check_meter_by_name() { + [test "$1" = "NOT"] && { expected_count=0; shift; } || expected_count=1 + for meter in $* ; do + # echo checking for $expected_count $meter in sb meter table + check_row_count meter $expected_count name=$meter + done +} + +# With acl_shared_log_meters unset, make sure no unique meters are in SB +check_meter_by_name meter_me +check_meter_by_name NOT meter_me__${acl1} meter_me__${acl2} +for other_meters in 'm1' 'm1,m2,m3' 'meter_Xe'; do + ovn-nbctl --wait=sb set nb_global . options:acl_shared_log_meters="$other_meters" + check_meter_by_name meter_me + check_meter_by_name NOT meter_me__${acl1} meter_me__${acl2} +done + +# Check variations where unique meters are in SB +for other_meters in 'm1,meter_me' 'm1,m2,meter_me,m3' 'meter_me,m1' 'meter_me'; do + ovn-nbctl --wait=sb set nb_global . options:acl_shared_log_meters="$other_meters" + check_meter_by_name meter_me meter_me__${acl1} meter_me__${acl2} +done + +# Change template meter and make sure that is reflected on acl meters as well +template_band=$(ovn-nbctl --bare --column=bands find meter name=meter_me) +ovn-nbctl --wait=sb set meter_band $template_band rate=123 +check_row_count meter_band 3 rate=123 + +# Check meter in logical flows for acl logs +check_acl_lflow acl_one meter_me__${acl1} +check_acl_lflow acl_two meter_me__${acl2} + +# Stop using meter for acl1 +ovn-nbctl --wait=sb clear acl $acl1 meter +check_meter_by_name meter_me meter_me__${acl2} +check_meter_by_name NOT meter_me__${acl1} +check_acl_lflow acl_two meter_me__${acl2} + +# Remove template Meter should remove all others as well +ovn-nbctl --wait=sb meter-del meter_me +check_row_count meter 0 +# Check that logical flow remains. It refers to a named row that does not exist. +check_acl_lflow acl_two meter_me__${acl2} + +# Re-add template meter and make sure acl2's meter is back in sb +ovn-nbctl --wait=sb meter-add meter_me drop 1 pktps +check_meter_by_name meter_me meter_me__${acl2} +check_meter_by_name NOT meter_me__${acl1} +check_acl_lflow acl_two meter_me__${acl2} + +# Remove acl2 +sw0=$(ovn-nbctl --bare --column=_uuid find logical_switch name=sw0) +ovn-nbctl --wait=sb remove logical_switch $sw0 acls $acl2 +check_meter_by_name meter_me +check_meter_by_name NOT meter_me__${acl1} meter_me__${acl2} + +AT_CLEANUP + AT_SETUP([datapath requested-tnl-key]) AT_KEYWORDS([requested tnl tunnel key keys]) ovn_start