From patchwork Thu Jul 8 16:40:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 1502514 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=2605:bc80:3010::136; helo=smtp3.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: 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=ZtpowoUx; dkim-atps=neutral Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) (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 ozlabs.org (Postfix) with ESMTPS id 4GLMVG6pQDz9sWc for ; Fri, 9 Jul 2021 02:40:38 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 5B97760C15; Thu, 8 Jul 2021 16:40:36 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org 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 yOxU4AU8DNMm; Thu, 8 Jul 2021 16:40:34 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp3.osuosl.org (Postfix) with ESMTPS id B340660AB3; Thu, 8 Jul 2021 16:40:33 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 7C8CFC001A; Thu, 8 Jul 2021 16:40:33 +0000 (UTC) X-Original-To: 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 22A47C000E for ; Thu, 8 Jul 2021 16:40:32 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 4D25A41D08 for ; Thu, 8 Jul 2021 16:40:28 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Authentication-Results: smtp2.osuosl.org (amavisd-new); dkim=pass (1024-bit key) header.d=redhat.com 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 u0PmMiPq1137 for ; Thu, 8 Jul 2021 16:40:26 +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 BB7E241D1C for ; Thu, 8 Jul 2021 16:40:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1625762425; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=RjG//TfaE9f/pyz3HK33wyF2QteKXuqf9whjXNp7o4U=; b=ZtpowoUxe6XE8b/snTQc3aujETisua4A6wCrdBQFt4TZAfCIuPQDKJPvVNFDTitb+DXM7j McL431X07QDobhmx+XZI/A7zZDQwCkv+4yqOzzU8LOQoSQFR3fm95U9jMjXgypq8MZhvzR W0xll0/oaTKW8hhKpQ7gGyBElUOtdvM= Received: from mail-ed1-f71.google.com (mail-ed1-f71.google.com [209.85.208.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-452-LrAraJW4NN28rO_bhpuGqA-1; Thu, 08 Jul 2021 12:40:22 -0400 X-MC-Unique: LrAraJW4NN28rO_bhpuGqA-1 Received: by mail-ed1-f71.google.com with SMTP id cn11-20020a0564020cabb0290396d773d4c7so3630728edb.18 for ; Thu, 08 Jul 2021 09:40:22 -0700 (PDT) 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:mime-version:content-transfer-encoding; bh=RjG//TfaE9f/pyz3HK33wyF2QteKXuqf9whjXNp7o4U=; b=NMVxOSy/CuT05mUhHn5A6wmHdLv6a60q5kDy9W+Yrjh33l/pHgBntW0kNhqE8Sqqnl dOO3+5cVwaxOxevArBpjyRSl0i2k12ZJh7aQ45zeGj7ND7dv/c5r2yy+NjQaoOr20JwH 0k3jHTARbH3XMGkYQ4ImNwLgFH4lsFA2/fKC2rBRI7AFYUEwbVwtBxfAwID1zPjGumBb vdkU5n6lx1AUSU2VpSqYXC/FIbajqaDSBoMC6iMnOAb2912zpt7sswCdjRgIiRiN6e7n rJ7CIMbGXsqrUZFp0UtH9YSCdxKgixYqpGciz0TkNYcWQ/xffmNRxWCnMdccY/7qQkwW NIVA== X-Gm-Message-State: AOAM533gthy/mGrWYZc5kYcqJb+u1NkKjDWaes9626LliGYkeTiOaTW5 v2aNHeYzmjlB4pvpeSV4DZ40mKVIChjI4dw/5Nss4fWKALR3dyc70+FNfb9Nhu+U3HN0q9ugolg LwpgLEs1IBEZkDgKSNIIeeokBfaZ24jmq/Xw8kvzSWsA9SlImEOg7oY6h6y7WBAIPPPBPlZZn7P Q= X-Received: by 2002:a05:6402:40c4:: with SMTP id z4mr40030773edb.364.1625762420576; Thu, 08 Jul 2021 09:40:20 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyWMZ6/6DiyMmlYwRfYKnvXz/qF3Bjx5gy0OKH+z9I7WD0RaCE+Howk7yjG2EZLSJr9HIYM3A== X-Received: by 2002:a05:6402:40c4:: with SMTP id z4mr40030744edb.364.1625762420292; Thu, 08 Jul 2021 09:40:20 -0700 (PDT) Received: from lore-desk.redhat.com (net-93-71-3-244.cust.vodafonedsl.it. [93.71.3.244]) by smtp.gmail.com with ESMTPSA id ee25sm1568103edb.6.2021.07.08.09.40.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 08 Jul 2021 09:40:19 -0700 (PDT) From: Lorenzo Bianconi To: dev@openvswitch.org Date: Thu, 8 Jul 2021 18:40:02 +0200 Message-Id: <8de7a63a25e244422f62d30c1898bea655702917.1625762235.git.lorenzo.bianconi@redhat.com> X-Mailer: git-send-email 2.31.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 Cc: dceara@redhat.com Subject: [ovs-dev] [PATCH v6 ovn 1/4] ovn-controller: Add support for Logical_Flow control 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: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" From: Dumitru Ceara Add a new 'controller_meter' column to OVN Southbound Logical_Flow table. This stores an optional string which should correspond to the Meter that must be used for rate limiting controller actions generated by packets hitting the flow. Add a new 'ofctrl_add_flow_metered' function to create a new 'ovn_flow' with an attached controller meter. Change ofctrl_check_and_add_flow to allow specifying a meter ID for packets that are punted to controller. Change consider_logical_flow to parse controller_meter from the logical flow and use it when building openflow entries. Add a new 'ctrl_meter_id' field to 'struct ovnact_encode_params' to be used when encoding controller actions from logical flow actions. Acked-by: Mark D. Gray Co-authored-by: Lorenzo Bianconi Signed-off-by: Lorenzo Bianconi Signed-off-by: Dumitru Ceara --- controller/lflow.c | 40 +++++++++++++++++++++++--- controller/ofctrl.c | 56 +++++++++++++++++++++++++----------- controller/ofctrl.h | 21 ++++++++++---- controller/physical.c | 9 +++--- include/ovn/actions.h | 2 ++ lib/actions.c | 66 +++++++++++++++++++++++-------------------- northd/ovn_northd.dl | 2 ++ ovn-sb.ovsschema | 4 ++- ovn-sb.xml | 6 ++++ 9 files changed, 143 insertions(+), 63 deletions(-) diff --git a/controller/lflow.c b/controller/lflow.c index 60aa011ff..f90c20136 100644 --- a/controller/lflow.c +++ b/controller/lflow.c @@ -575,6 +575,27 @@ update_conj_id_ofs(uint32_t *conj_id_ofs, uint32_t n_conjs) return false; } +static void +lflow_parse_ctrl_meter(const struct sbrec_logical_flow *lflow, + struct ovn_extend_table *meter_table, + uint32_t *meter_id) +{ + ovs_assert(meter_id); + *meter_id = NX_CTLR_NO_METER; + + if (lflow->controller_meter) { + *meter_id = ovn_extend_table_assign_id(meter_table, + lflow->controller_meter, + lflow->header_.uuid); + if (*meter_id == EXT_TABLE_ID_INVALID) { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); + VLOG_WARN_RL(&rl, "Unable to assign id for meter: %s", + lflow->controller_meter); + return; + } + } +} + static void add_matches_to_flow_table(const struct sbrec_logical_flow *lflow, const struct sbrec_datapath_binding *dp, @@ -592,6 +613,13 @@ add_matches_to_flow_table(const struct sbrec_logical_flow *lflow, .lfrr = l_ctx_out->lfrr, }; + /* Parse any meter to be used if this flow should punt packets to + * controller. + */ + uint32_t ctrl_meter_id = NX_CTLR_NO_METER; + lflow_parse_ctrl_meter(lflow, l_ctx_out->meter_table, + &ctrl_meter_id); + /* Encode OVN logical actions into OpenFlow. */ uint64_t ofpacts_stub[1024 / 8]; struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(ofpacts_stub); @@ -615,6 +643,7 @@ add_matches_to_flow_table(const struct sbrec_logical_flow *lflow, .ct_snat_vip_ptable = OFTABLE_CT_SNAT_FOR_VIP, .fdb_ptable = OFTABLE_GET_FDB, .fdb_lookup_ptable = OFTABLE_LOOKUP_FDB, + .ctrl_meter_id = ctrl_meter_id, }; ovnacts_encode(ovnacts->data, ovnacts->size, &ep, &ofpacts); @@ -639,9 +668,11 @@ add_matches_to_flow_table(const struct sbrec_logical_flow *lflow, } } if (!m->n) { - ofctrl_add_flow(l_ctx_out->flow_table, ptable, lflow->priority, - lflow->header_.uuid.parts[0], &m->match, &ofpacts, - &lflow->header_.uuid); + ofctrl_add_flow_metered(l_ctx_out->flow_table, ptable, + lflow->priority, + lflow->header_.uuid.parts[0], &m->match, + &ofpacts, &lflow->header_.uuid, + ctrl_meter_id); } else { uint64_t conj_stubs[64 / 8]; struct ofpbuf conj; @@ -659,7 +690,8 @@ add_matches_to_flow_table(const struct sbrec_logical_flow *lflow, ofctrl_add_or_append_flow(l_ctx_out->flow_table, ptable, lflow->priority, 0, - &m->match, &conj, &lflow->header_.uuid); + &m->match, &conj, &lflow->header_.uuid, + ctrl_meter_id); ofpbuf_uninit(&conj); } } diff --git a/controller/ofctrl.c b/controller/ofctrl.c index 053631590..eebb27567 100644 --- a/controller/ofctrl.c +++ b/controller/ofctrl.c @@ -66,6 +66,7 @@ struct ovn_flow { struct ofpact *ofpacts; size_t ofpacts_len; uint64_t cookie; + uint32_t ctrl_meter_id; /* Meter to be used for controller actions. */ }; /* A desired flow, in struct ovn_desired_flow_table, calculated by the @@ -220,7 +221,8 @@ static struct desired_flow *desired_flow_alloc( uint16_t priority, uint64_t cookie, const struct match *match, - const struct ofpbuf *actions); + const struct ofpbuf *actions, + uint32_t meter_id); static struct desired_flow *desired_flow_lookup( struct ovn_desired_flow_table *, const struct ovn_flow *target); @@ -1014,8 +1016,9 @@ link_flow_to_sb(struct ovn_desired_flow_table *flow_table, /* Flow table interfaces to the rest of ovn-controller. */ /* Adds a flow to 'desired_flows' with the specified 'match' and 'actions' to - * the OpenFlow table numbered 'table_id' with the given 'priority' and - * OpenFlow 'cookie'. The caller retains ownership of 'match' and 'actions'. + * the OpenFlow table numbered 'table_id' with the given 'priority', OpenFlow + * 'cookie' and 'meter_id'. The caller retains ownership of 'match' and + * 'actions'. * * The flow is also linked to the sb_uuid that generates it. * @@ -1024,15 +1027,15 @@ link_flow_to_sb(struct ovn_desired_flow_table *flow_table, * * The caller should initialize its own hmap to hold the flows. */ void -ofctrl_check_and_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 uuid *sb_uuid, - bool log_duplicate_flow) +ofctrl_check_and_add_flow_metered(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 uuid *sb_uuid, + uint32_t meter_id, bool log_duplicate_flow) { struct desired_flow *f = desired_flow_alloc(table_id, priority, cookie, - match, actions); + match, actions, meter_id); if (desired_flow_lookup_check_uuid(flow_table, &f->flow, sb_uuid)) { if (log_duplicate_flow) { @@ -1060,8 +1063,20 @@ ofctrl_add_flow(struct ovn_desired_flow_table *desired_flows, const struct match *match, const struct ofpbuf *actions, const struct uuid *sb_uuid) { - ofctrl_check_and_add_flow(desired_flows, table_id, priority, cookie, - match, actions, sb_uuid, true); + ofctrl_add_flow_metered(desired_flows, table_id, priority, cookie, + match, actions, sb_uuid, NX_CTLR_NO_METER); +} + +void +ofctrl_add_flow_metered(struct ovn_desired_flow_table *desired_flows, + uint8_t table_id, uint16_t priority, uint64_t cookie, + const struct match *match, + const struct ofpbuf *actions, + const struct uuid *sb_uuid, uint32_t meter_id) +{ + ofctrl_check_and_add_flow_metered(desired_flows, table_id, priority, + cookie, match, actions, sb_uuid, + meter_id, true); } /* Either add a new flow, or append actions on an existing flow. If the @@ -1072,12 +1087,14 @@ ofctrl_add_or_append_flow(struct ovn_desired_flow_table *desired_flows, uint8_t table_id, uint16_t priority, uint64_t cookie, const struct match *match, const struct ofpbuf *actions, - const struct uuid *sb_uuid) + const struct uuid *sb_uuid, + uint32_t meter_id) { struct desired_flow *existing; struct desired_flow *f; - f = desired_flow_alloc(table_id, priority, cookie, match, actions); + f = desired_flow_alloc(table_id, priority, cookie, match, actions, + meter_id); existing = desired_flow_lookup_conjunctive(desired_flows, &f->flow); if (existing) { /* There's already a flow with this particular match and action @@ -1282,7 +1299,7 @@ ofctrl_flood_remove_flows(struct ovn_desired_flow_table *flow_table, static void ovn_flow_init(struct ovn_flow *f, uint8_t table_id, uint16_t priority, uint64_t cookie, const struct match *match, - const struct ofpbuf *actions) + const struct ofpbuf *actions, uint32_t meter_id) { f->table_id = table_id; f->priority = priority; @@ -1291,11 +1308,13 @@ ovn_flow_init(struct ovn_flow *f, uint8_t table_id, uint16_t priority, f->ofpacts_len = actions->size; f->hash = ovn_flow_match_hash(f); f->cookie = cookie; + f->ctrl_meter_id = meter_id; } static struct desired_flow * desired_flow_alloc(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, + uint32_t meter_id) { struct desired_flow *f = xmalloc(sizeof *f); ovs_list_init(&f->references); @@ -1304,7 +1323,8 @@ desired_flow_alloc(uint8_t table_id, uint16_t priority, uint64_t cookie, ovs_list_init(&f->track_list_node); f->installed_flow = NULL; f->is_deleted = false; - ovn_flow_init(&f->flow, table_id, priority, cookie, match, actions); + ovn_flow_init(&f->flow, table_id, priority, cookie, match, actions, + meter_id); return f; } @@ -1330,6 +1350,7 @@ installed_flow_dup(struct desired_flow *src) dst->flow.ofpacts_len = src->flow.ofpacts_len; dst->flow.hash = src->flow.hash; dst->flow.cookie = src->flow.cookie; + dst->flow.ctrl_meter_id = src->flow.ctrl_meter_id; return dst; } @@ -1356,6 +1377,7 @@ desired_flow_lookup__(struct ovn_desired_flow_table *flow_table, struct ovn_flow *f = &d->flow; if (f->table_id == target->table_id && f->priority == target->priority + && f->ctrl_meter_id == target->ctrl_meter_id && minimatch_equal(&f->match, &target->match)) { if (!match_cb || match_cb(d, arg)) { diff --git a/controller/ofctrl.h b/controller/ofctrl.h index ead8088c5..526525ffd 100644 --- a/controller/ofctrl.h +++ b/controller/ofctrl.h @@ -80,7 +80,15 @@ void ofctrl_add_or_append_flow(struct ovn_desired_flow_table *desired_flows, uint8_t table_id, uint16_t priority, uint64_t cookie, const struct match *match, const struct ofpbuf *actions, - const struct uuid *sb_uuid); + const struct uuid *sb_uuid, + uint32_t meter_id); + +void ofctrl_add_flow_metered(struct ovn_desired_flow_table *desired_flows, + uint8_t table_id, uint16_t priority, + uint64_t cookie, const struct match *match, + const struct ofpbuf *actions, + const struct uuid *sb_uuid, + uint32_t meter_id); /* Removes a bundles of flows from the flow table for a specific sb_uuid. The * flows are removed only if they are not referenced by any other sb_uuid(s). @@ -110,11 +118,12 @@ 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 *); -void ofctrl_check_and_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 uuid *, bool log_duplicate_flow); +void ofctrl_check_and_add_flow_metered(struct ovn_desired_flow_table *, + uint8_t table_id, uint16_t priority, + uint64_t cookie, const struct match *, + const struct ofpbuf *ofpacts, + const struct uuid *, uint32_t meter_id, + bool log_duplicate_flow); bool ofctrl_is_connected(void); diff --git a/controller/physical.c b/controller/physical.c index 17ca5afbb..5fccc32ed 100644 --- a/controller/physical.c +++ b/controller/physical.c @@ -847,8 +847,8 @@ put_local_common_flows(uint32_t dp_key, * If a parent port has multiple child ports, then this if condition * will be hit multiple times, but we want to add only one flow. * ofctrl_add_flow() logs a warning message for duplicate flows. - * So use the function 'ofctrl_check_and_add_flow' which doesn't - * log a warning. + * So use the function 'ofctrl_check_and_add_flow_metered' which + * doesn't log a warning. * * Other option is to add this flow for all the ports which are not * nested containers. In which case we will add this flow for all the @@ -867,8 +867,9 @@ put_local_common_flows(uint32_t dp_key, put_load(ofp_to_u16(OFPP_NONE), MFF_IN_PORT, 0, 16, ofpacts_p); put_resubmit(OFTABLE_LOG_TO_PHY, ofpacts_p); put_stack(MFF_IN_PORT, ofpact_put_STACK_POP(ofpacts_p)); - ofctrl_check_and_add_flow(flow_table, OFTABLE_SAVE_INPORT, 100, 0, - &match, ofpacts_p, hc_uuid, false); + ofctrl_check_and_add_flow_metered(flow_table, OFTABLE_SAVE_INPORT, 100, + 0, &match, ofpacts_p, hc_uuid, + NX_CTLR_NO_METER, false); } } diff --git a/include/ovn/actions.h b/include/ovn/actions.h index f5eb01eb7..a33d02681 100644 --- a/include/ovn/actions.h +++ b/include/ovn/actions.h @@ -796,6 +796,8 @@ struct ovnact_encode_params { * 'get_fdb' to resubmit. */ uint8_t fdb_lookup_ptable; /* OpenFlow table for * 'lookup_fdb' to resubmit. */ + uint32_t ctrl_meter_id; /* Meter to be used if the resulting flow + sends packets to controller. */ }; void ovnacts_encode(const struct ovnact[], size_t ovnacts_len, diff --git a/lib/actions.c b/lib/actions.c index 7010fab2b..2355a9ace 100644 --- a/lib/actions.c +++ b/lib/actions.c @@ -105,10 +105,10 @@ encode_finish_controller_op(size_t ofs, struct ofpbuf *ofpacts) } static void -encode_controller_op(enum action_opcode opcode, struct ofpbuf *ofpacts) +encode_controller_op(enum action_opcode opcode, uint32_t meter_id, + struct ofpbuf *ofpacts) { - size_t ofs = encode_start_controller_op(opcode, false, NX_CTLR_NO_METER, - ofpacts); + size_t ofs = encode_start_controller_op(opcode, false, meter_id, ofpacts); encode_finish_controller_op(ofs, ofpacts); } @@ -1678,7 +1678,7 @@ encode_nested_actions(const struct ovnact_nest *on, * packet to ARP or NA and then send the packet and actions back to the * switch inside an OFPT_PACKET_OUT message. */ size_t oc_offset = encode_start_controller_op(opcode, false, - NX_CTLR_NO_METER, ofpacts); + ep->ctrl_meter_id, ofpacts); ofpacts_put_openflow_actions(inner_ofpacts.data, inner_ofpacts.size, ofpacts, OFP15_VERSION); encode_finish_controller_op(oc_offset, ofpacts); @@ -1729,10 +1729,10 @@ encode_ICMP6_ERROR(const struct ovnact_nest *on, static void encode_IGMP(const struct ovnact_null *a OVS_UNUSED, - const struct ovnact_encode_params *ep OVS_UNUSED, + const struct ovnact_encode_params *ep, struct ofpbuf *ofpacts) { - encode_controller_op(ACTION_OPCODE_IGMP, ofpacts); + encode_controller_op(ACTION_OPCODE_IGMP, ep->ctrl_meter_id, ofpacts); } static void @@ -1974,6 +1974,7 @@ format_PUT_ND(const struct ovnact_put_mac_bind *put_mac, struct ds *s) static void encode_put_mac(const struct ovnact_put_mac_bind *put_mac, + const struct ovnact_encode_params *ep, enum mf_field_id ip_field, enum action_opcode opcode, struct ofpbuf *ofpacts) { @@ -1983,24 +1984,24 @@ encode_put_mac(const struct ovnact_put_mac_bind *put_mac, { expr_resolve_field(&put_mac->mac), MFF_ETH_SRC } }; encode_setup_args(args, ARRAY_SIZE(args), ofpacts); - encode_controller_op(opcode, ofpacts); + encode_controller_op(opcode, ep->ctrl_meter_id, ofpacts); encode_restore_args(args, ARRAY_SIZE(args), ofpacts); } static void encode_PUT_ARP(const struct ovnact_put_mac_bind *put_mac, - const struct ovnact_encode_params *ep OVS_UNUSED, + const struct ovnact_encode_params *ep, struct ofpbuf *ofpacts) { - encode_put_mac(put_mac, MFF_REG0, ACTION_OPCODE_PUT_ARP, ofpacts); + encode_put_mac(put_mac, ep, MFF_REG0, ACTION_OPCODE_PUT_ARP, ofpacts); } static void encode_PUT_ND(const struct ovnact_put_mac_bind *put_mac, - const struct ovnact_encode_params *ep OVS_UNUSED, + const struct ovnact_encode_params *ep, struct ofpbuf *ofpacts) { - encode_put_mac(put_mac, MFF_XXREG0, ACTION_OPCODE_PUT_ND, ofpacts); + encode_put_mac(put_mac, ep, MFF_XXREG0, ACTION_OPCODE_PUT_ND, ofpacts); } static void @@ -2701,13 +2702,13 @@ encode_put_dhcpv6_option(const struct ovnact_gen_option *o, static void encode_PUT_DHCPV4_OPTS(const struct ovnact_put_opts *pdo, - const struct ovnact_encode_params *ep OVS_UNUSED, + const struct ovnact_encode_params *ep, struct ofpbuf *ofpacts) { struct mf_subfield dst = expr_resolve_field(&pdo->dst); size_t oc_offset = encode_start_controller_op(ACTION_OPCODE_PUT_DHCP_OPTS, - true, NX_CTLR_NO_METER, + true, ep->ctrl_meter_id, ofpacts); nx_put_header(ofpacts, dst.field->id, OFP15_VERSION, false); ovs_be32 ofs = htonl(dst.ofs); @@ -2754,13 +2755,13 @@ encode_PUT_DHCPV4_OPTS(const struct ovnact_put_opts *pdo, static void encode_PUT_DHCPV6_OPTS(const struct ovnact_put_opts *pdo, - const struct ovnact_encode_params *ep OVS_UNUSED, + const struct ovnact_encode_params *ep, struct ofpbuf *ofpacts) { struct mf_subfield dst = expr_resolve_field(&pdo->dst); size_t oc_offset = encode_start_controller_op( - ACTION_OPCODE_PUT_DHCPV6_OPTS, true, NX_CTLR_NO_METER, ofpacts); + ACTION_OPCODE_PUT_DHCPV6_OPTS, true, ep->ctrl_meter_id, ofpacts); nx_put_header(ofpacts, dst.field->id, OFP15_VERSION, false); ovs_be32 ofs = htonl(dst.ofs); ofpbuf_put(ofpacts, &ofs, sizeof ofs); @@ -2787,10 +2788,11 @@ format_DHCP6_REPLY(const struct ovnact_null *a OVS_UNUSED, struct ds *s) static void encode_DHCP6_REPLY(const struct ovnact_null *a OVS_UNUSED, - const struct ovnact_encode_params *ep OVS_UNUSED, + const struct ovnact_encode_params *ep, struct ofpbuf *ofpacts) { - encode_controller_op(ACTION_OPCODE_DHCP6_SERVER, ofpacts); + encode_controller_op(ACTION_OPCODE_DHCP6_SERVER, ep->ctrl_meter_id, + ofpacts); } static void @@ -2801,10 +2803,11 @@ format_BFD_MSG(const struct ovnact_null *a OVS_UNUSED, struct ds *s) static void encode_BFD_MSG(const struct ovnact_null *a OVS_UNUSED, - const struct ovnact_encode_params *ep OVS_UNUSED, + const struct ovnact_encode_params *ep, struct ofpbuf *ofpacts) { - encode_controller_op(ACTION_OPCODE_BFD_MSG, ofpacts); + encode_controller_op(ACTION_OPCODE_BFD_MSG, ep->ctrl_meter_id, + ofpacts); } static void @@ -2899,13 +2902,13 @@ format_DNS_LOOKUP(const struct ovnact_result *dl, struct ds *s) static void encode_DNS_LOOKUP(const struct ovnact_result *dl, - const struct ovnact_encode_params *ep OVS_UNUSED, + const struct ovnact_encode_params *ep, struct ofpbuf *ofpacts) { struct mf_subfield dst = expr_resolve_field(&dl->dst); size_t oc_offset = encode_start_controller_op(ACTION_OPCODE_DNS_LOOKUP, - true, NX_CTLR_NO_METER, + true, ep->ctrl_meter_id, ofpacts); nx_put_header(ofpacts, dst.field->id, OFP15_VERSION, false); ovs_be32 ofs = htonl(dst.ofs); @@ -3083,13 +3086,13 @@ encode_put_nd_ra_option(const struct ovnact_gen_option *o, static void encode_PUT_ND_RA_OPTS(const struct ovnact_put_opts *po, - const struct ovnact_encode_params *ep OVS_UNUSED, + const struct ovnact_encode_params *ep, struct ofpbuf *ofpacts) { struct mf_subfield dst = expr_resolve_field(&po->dst); size_t oc_offset = encode_start_controller_op( - ACTION_OPCODE_PUT_ND_RA_OPTS, true, NX_CTLR_NO_METER, ofpacts); + ACTION_OPCODE_PUT_ND_RA_OPTS, true, ep->ctrl_meter_id, ofpacts); nx_put_header(ofpacts, dst.field->id, OFP15_VERSION, false); ovs_be32 ofs = htonl(dst.ofs); ofpbuf_put(ofpacts, &ofs, sizeof ofs); @@ -3372,7 +3375,7 @@ format_OVNFIELD_LOAD(const struct ovnact_load *load , struct ds *s) static void encode_OVNFIELD_LOAD(const struct ovnact_load *load, - const struct ovnact_encode_params *ep OVS_UNUSED, + const struct ovnact_encode_params *ep, struct ofpbuf *ofpacts) { const struct ovn_field *f = ovn_field_from_name(load->dst.symbol->name); @@ -3380,7 +3383,7 @@ encode_OVNFIELD_LOAD(const struct ovnact_load *load, case OVN_ICMP4_FRAG_MTU: { size_t oc_offset = encode_start_controller_op( ACTION_OPCODE_PUT_ICMP4_FRAG_MTU, true, - NX_CTLR_NO_METER, ofpacts); + ep->ctrl_meter_id, ofpacts); ofpbuf_put(ofpacts, &load->imm.value.be16_int, sizeof(ovs_be16)); encode_finish_controller_op(oc_offset, ofpacts); break; @@ -3388,7 +3391,7 @@ encode_OVNFIELD_LOAD(const struct ovnact_load *load, case OVN_ICMP6_FRAG_MTU: { size_t oc_offset = encode_start_controller_op( ACTION_OPCODE_PUT_ICMP6_FRAG_MTU, true, - NX_CTLR_NO_METER, ofpacts); + ep->ctrl_meter_id, ofpacts); ofpbuf_put(ofpacts, &load->imm.value.be32_int, sizeof(ovs_be32)); encode_finish_controller_op(oc_offset, ofpacts); break; @@ -3492,7 +3495,7 @@ encode_BIND_VPORT(const struct ovnact_bind_vport *vp, }; encode_setup_args(args, ARRAY_SIZE(args), ofpacts); size_t oc_offset = encode_start_controller_op(ACTION_OPCODE_BIND_VPORT, - false, NX_CTLR_NO_METER, + false, ep->ctrl_meter_id, ofpacts); ovs_be32 vp_key = htonl(vport_key); ofpbuf_put(ofpacts, &vp_key, sizeof(ovs_be32)); @@ -3530,14 +3533,15 @@ format_HANDLE_SVC_CHECK(const struct ovnact_handle_svc_check *svc_chk, static void encode_HANDLE_SVC_CHECK(const struct ovnact_handle_svc_check *svc_chk, - const struct ovnact_encode_params *ep OVS_UNUSED, + const struct ovnact_encode_params *ep, struct ofpbuf *ofpacts) { const struct arg args[] = { { expr_resolve_field(&svc_chk->port), MFF_LOG_INPORT }, }; encode_setup_args(args, ARRAY_SIZE(args), ofpacts); - encode_controller_op(ACTION_OPCODE_HANDLE_SVC_CHECK, ofpacts); + encode_controller_op(ACTION_OPCODE_HANDLE_SVC_CHECK, ep->ctrl_meter_id, + ofpacts); encode_restore_args(args, ARRAY_SIZE(args), ofpacts); } @@ -3786,7 +3790,7 @@ format_PUT_FDB(const struct ovnact_put_fdb *put_fdb, struct ds *s) static void encode_PUT_FDB(const struct ovnact_put_fdb *put_fdb, - const struct ovnact_encode_params *ep OVS_UNUSED, + const struct ovnact_encode_params *ep, struct ofpbuf *ofpacts) { const struct arg args[] = { @@ -3794,7 +3798,7 @@ encode_PUT_FDB(const struct ovnact_put_fdb *put_fdb, { expr_resolve_field(&put_fdb->mac), MFF_ETH_SRC } }; encode_setup_args(args, ARRAY_SIZE(args), ofpacts); - encode_controller_op(ACTION_OPCODE_PUT_FDB, ofpacts); + encode_controller_op(ACTION_OPCODE_PUT_FDB, ep->ctrl_meter_id, ofpacts); encode_restore_args(args, ARRAY_SIZE(args), ofpacts); } diff --git a/northd/ovn_northd.dl b/northd/ovn_northd.dl index e27c944a0..4a138977a 100644 --- a/northd/ovn_northd.dl +++ b/northd/ovn_northd.dl @@ -1672,6 +1672,7 @@ for (f in AggregatedFlow()) { .pipeline = pipeline, .table_id = f.stage.table_id, .priority = f.priority, + .controller_meter = None, .__match = f.__match, .actions = f.actions, .external_ids = external_ids) @@ -1684,6 +1685,7 @@ for (f in AggregatedFlow()) { .pipeline = pipeline, .table_id = f.stage.table_id, .priority = f.priority, + .controller_meter = None, .__match = f.__match, .actions = f.actions, .external_ids = external_ids); diff --git a/ovn-sb.ovsschema b/ovn-sb.ovsschema index bbf60781d..fe7f858f7 100644 --- a/ovn-sb.ovsschema +++ b/ovn-sb.ovsschema @@ -1,7 +1,7 @@ { "name": "OVN_Southbound", "version": "20.18.0", - "cksum": "1816525029 26536", + "cksum": "60276371 26668", "tables": { "SB_Global": { "columns": { @@ -109,6 +109,8 @@ "maxInteger": 65535}}}, "match": {"type": "string"}, "actions": {"type": "string"}, + "controller_meter": {"type": {"key": {"type": "string"}, + "min": 0, "max": 1}}, "external_ids": { "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}}}, diff --git a/ovn-sb.xml b/ovn-sb.xml index 69de4551b..2d6528c98 100644 --- a/ovn-sb.xml +++ b/ovn-sb.xml @@ -2441,6 +2441,12 @@ tcp.flags = RST; + + The name of the meter in table to be used for + all packets that the logical flow might send to + ovn-controller. + + Human-readable name for this flow's stage in the pipeline.