From patchwork Sat Nov 14 07:56:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Maximets X-Patchwork-Id: 1400232 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=ovn.org 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 4CY73J2ch3z9sRK for ; Sat, 14 Nov 2020 18:57:15 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id D2918876D7; Sat, 14 Nov 2020 07:57:11 +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 8HsxGJT1ixw6; Sat, 14 Nov 2020 07:57:08 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id F126D87648; Sat, 14 Nov 2020 07:57:06 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id D1AACC1DA2; Sat, 14 Nov 2020 07:57:06 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 9CDC4C0800 for ; Sat, 14 Nov 2020 07:57:05 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 9907487593 for ; Sat, 14 Nov 2020 07:57:05 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id nnAXmb+-9amJ for ; Sat, 14 Nov 2020 07:57:03 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by whitealder.osuosl.org (Postfix) with ESMTPS id 2029A8759C for ; Sat, 14 Nov 2020 07:57:02 +0000 (UTC) X-Originating-IP: 78.45.89.65 Received: from im-t490s.redhat.com (ip-78-45-89-65.net.upcbroadband.cz [78.45.89.65]) (Authenticated sender: i.maximets@ovn.org) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id 3AC94FF808; Sat, 14 Nov 2020 07:57:01 +0000 (UTC) From: Ilya Maximets To: ovs-dev@openvswitch.org Date: Sat, 14 Nov 2020 08:56:48 +0100 Message-Id: <20201114075653.9142-2-i.maximets@ovn.org> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20201114075653.9142-1-i.maximets@ovn.org> References: <20201114075653.9142-1-i.maximets@ovn.org> MIME-Version: 1.0 Cc: Ilya Maximets Subject: [ovs-dev] [PATCH ovn 1/6] tests: Sort flow and database dumps. 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" The order in which flows appears in the dump is not strictly determined. Need to sort the output to make tests independent from the system and implementation details. Signed-off-by: Ilya Maximets --- tests/ovn-northd.at | 6 +++--- tests/ovn.at | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index 26376c367..ee8aba10c 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -1174,7 +1174,7 @@ wait_row_count Service_Monitor 1 port=1000 AT_CAPTURE_FILE([sbflows9]) OVS_WAIT_FOR_OUTPUT( - [ovn-sbctl dump-flows sw0 | tee sbflows9 | grep ct_lb | grep priority=120 | sed 's/table=..//'], + [ovn-sbctl dump-flows sw0 | tee sbflows9 | grep ct_lb | grep priority=120 | sed 's/table=..//' | sort], 0, [ (ls_in_stateful ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(ct_lb(backends=10.0.0.3:80);) (ls_in_stateful ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.40 && tcp.dst == 1000), action=(ct_lb(backends=10.0.0.3:1000);) @@ -1187,7 +1187,7 @@ wait_row_count Service_Monitor 1 logical_port=sw1-p1 status=online AT_CAPTURE_FILE([sbflows10]) OVS_WAIT_FOR_OUTPUT( - [ovn-sbctl dump-flows sw0 | tee sbflows10 | grep ct_lb | grep priority=120 | sed 's/table=..//'], + [ovn-sbctl dump-flows sw0 | tee sbflows10 | grep ct_lb | grep priority=120 | sed 's/table=..//' | sort], 0, [ (ls_in_stateful ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(ct_lb(backends=10.0.0.3:80,20.0.0.3:80);) (ls_in_stateful ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.40 && tcp.dst == 1000), action=(ct_lb(backends=10.0.0.3:1000,20.0.0.3:80);) @@ -1197,7 +1197,7 @@ OVS_WAIT_FOR_OUTPUT( check ovn-nbctl --wait=sb ls-lb-add sw1 lb1 AT_CAPTURE_FILE([sbflows11]) OVS_WAIT_FOR_OUTPUT( - [ovn-sbctl dump-flows sw1 | tee sbflows11 | grep ct_lb | grep priority=120 | sed 's/table=..//'], + [ovn-sbctl dump-flows sw1 | tee sbflows11 | grep ct_lb | grep priority=120 | sed 's/table=..//' | sort], 0, [dnl (ls_in_stateful ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(ct_lb(backends=10.0.0.3:80,20.0.0.3:80);) (ls_in_stateful ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.40 && tcp.dst == 1000), action=(ct_lb(backends=10.0.0.3:1000,20.0.0.3:80);) diff --git a/tests/ovn.at b/tests/ovn.at index c0219bbd4..c0065472a 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -16341,7 +16341,7 @@ ovn-nbctl --wait=hv sync ovn-sbctl dump-flows sw0 > sw0-flows AT_CAPTURE_FILE([sw0-flows]) -AT_CHECK([grep ls_in_arp_rsp sw0-flows | grep bind_vport | sed 's/table=../table=??/'], [0], [dnl +AT_CHECK([grep ls_in_arp_rsp sw0-flows | grep bind_vport | sed 's/table=../table=??/' | sort], [0], [dnl table=??(ls_in_arp_rsp ), priority=100 , match=(inport == "sw0-p1" && ((arp.op == 1 && arp.spa == 10.0.0.10 && arp.tpa == 10.0.0.10) || (arp.op == 2 && arp.spa == 10.0.0.10))), action=(bind_vport("sw0-vir", inport); next;) table=??(ls_in_arp_rsp ), priority=100 , match=(inport == "sw0-p2" && ((arp.op == 1 && arp.spa == 10.0.0.10 && arp.tpa == 10.0.0.10) || (arp.op == 2 && arp.spa == 10.0.0.10))), action=(bind_vport("sw0-vir", inport); next;) table=??(ls_in_arp_rsp ), priority=100 , match=(inport == "sw0-p3" && ((arp.op == 1 && arp.spa == 10.0.0.10 && arp.tpa == 10.0.0.10) || (arp.op == 2 && arp.spa == 10.0.0.10))), action=(bind_vport("sw0-vir", inport); next;) From patchwork Sat Nov 14 07:56:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Maximets X-Patchwork-Id: 1400234 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=ovn.org 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 4CY73J3WJxz9sTv for ; Sat, 14 Nov 2020 18:57:15 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 8AE1F8764F; Sat, 14 Nov 2020 07:57:11 +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 54PeipfOivTm; Sat, 14 Nov 2020 07:57:09 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id ED6E4875AD; Sat, 14 Nov 2020 07:57:08 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id D362FC0891; Sat, 14 Nov 2020 07:57:08 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 13FC7C0891 for ; Sat, 14 Nov 2020 07:57:07 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id D9EE187984 for ; Sat, 14 Nov 2020 07:57:06 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id n-SFCHVKC5fh for ; Sat, 14 Nov 2020 07:57:05 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by hemlock.osuosl.org (Postfix) with ESMTPS id 3F24E87946 for ; Sat, 14 Nov 2020 07:57:05 +0000 (UTC) X-Originating-IP: 78.45.89.65 Received: from im-t490s.redhat.com (ip-78-45-89-65.net.upcbroadband.cz [78.45.89.65]) (Authenticated sender: i.maximets@ovn.org) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id 508E1FF804; Sat, 14 Nov 2020 07:57:03 +0000 (UTC) From: Ilya Maximets To: ovs-dev@openvswitch.org Date: Sat, 14 Nov 2020 08:56:49 +0100 Message-Id: <20201114075653.9142-3-i.maximets@ovn.org> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20201114075653.9142-1-i.maximets@ovn.org> References: <20201114075653.9142-1-i.maximets@ovn.org> MIME-Version: 1.0 Cc: Ilya Maximets Subject: [ovs-dev] [PATCH ovn 2/6] ovn-sb.ovsschema: Add Logical Datapath Groups. 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" New table 'Logical_Datapath_Group'. Each row of this table will store a set of logical datapaths. Each logical flow now has a reference to a logical datapath group, so the same logical flow could be applied to many different logical datapaths in a group. Signed-off-by: Ilya Maximets --- ovn-sb.ovsschema | 22 ++++++++++++++++++---- ovn-sb.xml | 42 +++++++++++++++++++++++++++++++----------- 2 files changed, 49 insertions(+), 15 deletions(-) diff --git a/ovn-sb.ovsschema b/ovn-sb.ovsschema index d1c506a22..71574261e 100644 --- a/ovn-sb.ovsschema +++ b/ovn-sb.ovsschema @@ -1,7 +1,7 @@ { "name": "OVN_Southbound", - "version": "2.10.0", - "cksum": "2548342632 22615", + "version": "20.12.0", + "cksum": "2311403201 23260", "tables": { "SB_Global": { "columns": { @@ -90,8 +90,14 @@ "isRoot": true}, "Logical_Flow": { "columns": { - "logical_datapath": {"type": {"key": {"type": "uuid", - "refTable": "Datapath_Binding"}}}, + "logical_datapath": + {"type": {"key": {"type": "uuid", + "refTable": "Datapath_Binding"}, + "min": 0, "max": 1}}, + "logical_datapath_group": + {"type": {"key": {"type": "uuid", + "refTable": "Logical_Datapath_Group"}, + "min": 0, "max": 1}}, "pipeline": {"type": {"key": {"type": "string", "enum": ["set", ["ingress", "egress"]]}}}, @@ -107,6 +113,14 @@ "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}}}, "isRoot": true}, + "Logical_Datapath_Group": { + "columns": { + "datapaths": + {"type": {"key": {"type": "uuid", + "refTable": "Datapath_Binding", + "refType": "weak"}, + "min": 0, "max": "unlimited"}}}, + "isRoot": false}, "Multicast_Group": { "columns": { "datapath": {"type": {"key": {"type": "uuid", diff --git a/ovn-sb.xml b/ovn-sb.xml index ebe2893e3..b70f5aa64 100644 --- a/ovn-sb.xml +++ b/ovn-sb.xml @@ -579,11 +579,12 @@

In more detail, to start, OVN searches the - table for a row with correct , a of ingress, a - of 0, and a that is true for the packet. If none - is found, OVN drops the packet. If OVN finds more than one, it chooses - the match with the highest . Then OVN executes + table for a row with correct or a + , a of + ingress, a of 0, and a that is true for the packet. If none is found, OVN + drops the packet. If OVN finds more than one, it chooses the match with + the highest . Then OVN executes each of the actions specified in the row's column, in the order specified. Some actions, such as those to modify packet headers, require no further details. The next and @@ -616,12 +617,12 @@

To execute the egress pipeline, OVN again searches the table for a row with correct , a of 0, a that is true for the packet, but now looking for a of egress. If no matching row is found, - the output becomes a no-op. Otherwise, OVN executes the actions for the - matching flow (which is chosen from multiple, if necessary, as already - described). + column="logical_datapath"/> or a , + a of 0, a that is true for + the packet, but now looking for a of + egress. If no matching row is found, the output becomes a + no-op. Otherwise, OVN executes the actions for the matching flow (which + is chosen from multiple, if necessary, as already described).

@@ -652,6 +653,11 @@ The logical datapath to which the logical flow belongs. + + The group of logical datapaths to which the logical flow belongs. This + means that the same logical flow belongs to all datapaths in a group. + +

The primary flows used for deciding on a packet's destination are the @@ -2354,6 +2360,20 @@ tcp.flags = RST; + +

+ Each row in this table represents a group of logical datapaths referenced + by the column + in the table. +

+ + +

+ List of entries. +

+
+
+

The rows in this table define multicast groups of logical ports. From patchwork Sat Nov 14 07:56:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Maximets X-Patchwork-Id: 1400237 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=ovn.org 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 4CY73f0W9tz9sRK for ; Sat, 14 Nov 2020 18:57:34 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 5EADE8767C; Sat, 14 Nov 2020 07:57:32 +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 rnXomhlkZ65A; Sat, 14 Nov 2020 07:57:25 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id 490D087650; Sat, 14 Nov 2020 07:57:25 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 1B49CC1DAA; Sat, 14 Nov 2020 07:57:25 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 6E43EC0800 for ; Sat, 14 Nov 2020 07:57:23 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 51E562E2EA for ; Sat, 14 Nov 2020 07:57:23 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id pGNhwrh0b8lP for ; Sat, 14 Nov 2020 07:57:12 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by silver.osuosl.org (Postfix) with ESMTPS id 6735E204E9 for ; Sat, 14 Nov 2020 07:57:07 +0000 (UTC) X-Originating-IP: 78.45.89.65 Received: from im-t490s.redhat.com (ip-78-45-89-65.net.upcbroadband.cz [78.45.89.65]) (Authenticated sender: i.maximets@ovn.org) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id 10708FF805; Sat, 14 Nov 2020 07:57:04 +0000 (UTC) From: Ilya Maximets To: ovs-dev@openvswitch.org Date: Sat, 14 Nov 2020 08:56:50 +0100 Message-Id: <20201114075653.9142-4-i.maximets@ovn.org> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20201114075653.9142-1-i.maximets@ovn.org> References: <20201114075653.9142-1-i.maximets@ovn.org> MIME-Version: 1.0 Cc: Ilya Maximets Subject: [ovs-dev] [PATCH ovn 3/6] northd: Add support for Logical Datapath Groups. 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" Signed-off-by: Ilya Maximets --- lib/ovn-util.c | 14 +--- lib/ovn-util.h | 3 +- northd/ovn-northd.c | 166 ++++++++++++++++++++++++++++++++++---------- 3 files changed, 133 insertions(+), 50 deletions(-) diff --git a/lib/ovn-util.c b/lib/ovn-util.c index 18aac8da3..a7fdd431d 100644 --- a/lib/ovn-util.c +++ b/lib/ovn-util.c @@ -504,24 +504,16 @@ ovn_is_known_nb_lsp_type(const char *type) uint32_t sbrec_logical_flow_hash(const struct sbrec_logical_flow *lf) { - const struct sbrec_datapath_binding *ld = lf->logical_datapath; - if (!ld) { - return 0; - } - - return ovn_logical_flow_hash(&ld->header_.uuid, - lf->table_id, lf->pipeline, + return ovn_logical_flow_hash(lf->table_id, lf->pipeline, lf->priority, lf->match, lf->actions); } uint32_t -ovn_logical_flow_hash(const struct uuid *logical_datapath, - uint8_t table_id, const char *pipeline, +ovn_logical_flow_hash(uint8_t table_id, const char *pipeline, uint16_t priority, const char *match, const char *actions) { - size_t hash = uuid_hash(logical_datapath); - hash = hash_2words((table_id << 16) | priority, hash); + size_t hash = hash_2words((table_id << 16) | priority, 0); hash = hash_string(pipeline, hash); hash = hash_string(match, hash); return hash_string(actions, hash); diff --git a/lib/ovn-util.h b/lib/ovn-util.h index 3496673b2..9262b05e4 100644 --- a/lib/ovn-util.h +++ b/lib/ovn-util.h @@ -102,8 +102,7 @@ const char *db_table_usage(struct ds *tables, bool ovn_is_known_nb_lsp_type(const char *type); uint32_t sbrec_logical_flow_hash(const struct sbrec_logical_flow *); -uint32_t ovn_logical_flow_hash(const struct uuid *logical_datapath, - uint8_t table_id, const char *pipeline, +uint32_t ovn_logical_flow_hash(uint8_t table_id, const char *pipeline, uint16_t priority, const char *match, const char *actions); bool datapath_is_switch(const struct sbrec_datapath_binding *); diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index 4d4190cb9..782a539dc 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -25,6 +25,7 @@ #include "openvswitch/dynamic-string.h" #include "fatal-signal.h" #include "hash.h" +#include "hmapx.h" #include "openvswitch/hmap.h" #include "openvswitch/json.h" #include "ovn/lex.h" @@ -4174,7 +4175,7 @@ ovn_igmp_group_destroy(struct hmap *igmp_groups, struct ovn_lflow { struct hmap_node hmap_node; - struct ovn_datapath *od; + struct hmapx od; /* Hash map of 'struct ovn_datapath *'. */ enum ovn_stage stage; uint16_t priority; char *match; @@ -4186,8 +4187,7 @@ struct ovn_lflow { static size_t ovn_lflow_hash(const struct ovn_lflow *lflow) { - return ovn_logical_flow_hash(&lflow->od->sb->header_.uuid, - ovn_stage_get_table(lflow->stage), + return ovn_logical_flow_hash(ovn_stage_get_table(lflow->stage), ovn_stage_get_pipeline_name(lflow->stage), lflow->priority, lflow->match, lflow->actions); @@ -4205,20 +4205,19 @@ ovn_lflow_hint(const struct ovsdb_idl_row *row) static bool ovn_lflow_equal(const struct ovn_lflow *a, const struct ovn_lflow *b) { - return (a->od == b->od - && a->stage == b->stage + return (a->stage == b->stage && a->priority == b->priority && !strcmp(a->match, b->match) && !strcmp(a->actions, b->actions)); } static void -ovn_lflow_init(struct ovn_lflow *lflow, struct ovn_datapath *od, +ovn_lflow_init(struct ovn_lflow *lflow, enum ovn_stage stage, uint16_t priority, char *match, char *actions, char *stage_hint, const char *where) { - lflow->od = od; + hmapx_init(&lflow->od); lflow->stage = stage; lflow->priority = priority; lflow->match = match; @@ -4227,6 +4226,34 @@ ovn_lflow_init(struct ovn_lflow *lflow, struct ovn_datapath *od, lflow->where = where; } +static void +ovn_lflow_destroy(struct hmap *lflows, struct ovn_lflow *lflow) +{ + if (lflow) { + if (lflows) { + hmap_remove(lflows, &lflow->hmap_node); + } + hmapx_destroy(&lflow->od); + free(lflow->match); + free(lflow->actions); + free(lflow->stage_hint); + free(lflow); + } +} + +static struct ovn_lflow * +ovn_lflow_find_by_lflow(const struct hmap *lflows, + const struct ovn_lflow *target, size_t hash) +{ + struct ovn_lflow *lflow; + HMAP_FOR_EACH_WITH_HASH (lflow, hmap_node, hash, lflows) { + if (ovn_lflow_equal(lflow, target)) { + return lflow; + } + } + return NULL; +} + /* Adds a row with the specified contents to the Logical_Flow table. */ static void ovn_lflow_add_at(struct hmap *lflow_map, struct ovn_datapath *od, @@ -4236,11 +4263,23 @@ ovn_lflow_add_at(struct hmap *lflow_map, struct ovn_datapath *od, { ovs_assert(ovn_stage_to_datapath_type(stage) == ovn_datapath_get_type(od)); - struct ovn_lflow *lflow = xmalloc(sizeof *lflow); - ovn_lflow_init(lflow, od, stage, priority, + struct ovn_lflow *old_lflow, *lflow; + size_t hash; + + lflow = xmalloc(sizeof *lflow); + ovn_lflow_init(lflow, stage, priority, xstrdup(match), xstrdup(actions), ovn_lflow_hint(stage_hint), where); - hmap_insert(lflow_map, &lflow->hmap_node, ovn_lflow_hash(lflow)); + + hash = ovn_lflow_hash(lflow); + old_lflow = ovn_lflow_find_by_lflow(lflow_map, lflow, hash); + if (old_lflow) { + ovn_lflow_destroy(NULL, lflow); + hmapx_add(&old_lflow->od, od); + } else { + hmapx_add(&lflow->od, od); + hmap_insert(lflow_map, &lflow->hmap_node, hash); + } } /* Adds a row with the specified contents to the Logical_Flow table. */ @@ -4254,34 +4293,16 @@ ovn_lflow_add_at(struct hmap *lflow_map, struct ovn_datapath *od, ACTIONS, NULL) static struct ovn_lflow * -ovn_lflow_find(struct hmap *lflows, struct ovn_datapath *od, +ovn_lflow_find(struct hmap *lflows, enum ovn_stage stage, uint16_t priority, const char *match, const char *actions, uint32_t hash) { struct ovn_lflow target; - ovn_lflow_init(&target, od, stage, priority, + ovn_lflow_init(&target, stage, priority, CONST_CAST(char *, match), CONST_CAST(char *, actions), NULL, NULL); - struct ovn_lflow *lflow; - HMAP_FOR_EACH_WITH_HASH (lflow, hmap_node, hash, lflows) { - if (ovn_lflow_equal(lflow, &target)) { - return lflow; - } - } - return NULL; -} - -static void -ovn_lflow_destroy(struct hmap *lflows, struct ovn_lflow *lflow) -{ - if (lflow) { - hmap_remove(lflows, &lflow->hmap_node); - free(lflow->match); - free(lflow->actions); - free(lflow->stage_hint); - free(lflow); - } + return ovn_lflow_find_by_lflow(lflows, &target, hash); } /* Appends port security constraints on L2 address field 'eth_addr_field' @@ -11295,6 +11316,28 @@ build_lswitch_and_lrouter_flows(struct hmap *datapaths, struct hmap *ports, } +static void +ovn_sb_set_lflow_logical_datapath_group( + struct northd_context *ctx, + const struct sbrec_logical_flow *sbflow, + const struct hmapx *od) +{ + struct sbrec_logical_datapath_group *dp_group; + const struct sbrec_datapath_binding **sb; + const struct hmapx_node *node; + int n = 0; + + sb = xmalloc(hmapx_count(od) * sizeof *sb); + HMAPX_FOR_EACH (node, od) { + sb[n++] = ((struct ovn_datapath *) node->data)->sb; + } + dp_group = sbrec_logical_datapath_group_insert(ctx->ovnsb_txn); + sbrec_logical_datapath_group_set_datapaths( + dp_group, (struct sbrec_datapath_binding **) sb, n); + free(sb); + sbrec_logical_flow_set_logical_datapath_group(sbflow, dp_group); +} + /* Updates the Logical_Flow and Multicast_Group tables in the OVN_SB database, * constructing their contents based on the OVN_NB database. */ static void @@ -11313,25 +11356,67 @@ build_lflows(struct northd_context *ctx, struct hmap *datapaths, /* Push changes to the Logical_Flow table to database. */ const struct sbrec_logical_flow *sbflow, *next_sbflow; SBREC_LOGICAL_FLOW_FOR_EACH_SAFE (sbflow, next_sbflow, ctx->ovnsb_idl) { - struct ovn_datapath *od - = ovn_datapath_from_sbrec(datapaths, sbflow->logical_datapath); + struct sbrec_logical_datapath_group *dp_group + = sbflow->logical_datapath_group; + struct ovn_datapath **od = xmalloc(dp_group->n_datapaths * sizeof *od); + enum ovn_datapath_type dp_type; + int n_valid_datapaths = 0; + size_t i; + + /* Check all logical datapaths from the group. */ + for (i = 0; i < dp_group->n_datapaths; i++) { + od[i] = ovn_datapath_from_sbrec(datapaths, dp_group->datapaths[i]); + if (!od[i] || ovn_datapath_is_stale(od[i])) { + od[i] = NULL; + continue; + } + n_valid_datapaths++; + dp_type = od[i]->nbs ? DP_SWITCH : DP_ROUTER; + } - if (!od || ovn_datapath_is_stale(od)) { + if (!n_valid_datapaths) { + /* This lflow has no valid logical datapaths. */ + sbrec_logical_datapath_group_delete(dp_group); sbrec_logical_flow_delete(sbflow); + free(od); continue; } - enum ovn_datapath_type dp_type = od->nbs ? DP_SWITCH : DP_ROUTER; enum ovn_pipeline pipeline = !strcmp(sbflow->pipeline, "ingress") ? P_IN : P_OUT; struct ovn_lflow *lflow = ovn_lflow_find( - &lflows, od, ovn_stage_build(dp_type, pipeline, sbflow->table_id), + &lflows, ovn_stage_build(dp_type, pipeline, sbflow->table_id), sbflow->priority, sbflow->match, sbflow->actions, sbflow->hash); + if (lflow) { + /* This is a valid lflow. Checking if the datapath group needs + * updates. */ + bool update_datapath_group = false; + + if (dp_group->n_datapaths != hmapx_count(&lflow->od)) { + update_datapath_group = true; + } else { + for (i = 0; i < dp_group->n_datapaths; i++) { + if (od[i] && !hmapx_contains(&lflow->od, od[i])) { + update_datapath_group = true; + break; + } + } + } + + if (update_datapath_group) { + /* Re-creating datapath group since there are changes. */ + sbrec_logical_datapath_group_delete(dp_group); + ovn_sb_set_lflow_logical_datapath_group(ctx, + sbflow, &lflow->od); + } + /* This lflow updated. Not needed anymore. */ ovn_lflow_destroy(&lflows, lflow); } else { + sbrec_logical_datapath_group_delete(dp_group); sbrec_logical_flow_delete(sbflow); } + free(od); } struct ovn_lflow *lflow, *next_lflow; HMAP_FOR_EACH_SAFE (lflow, next_lflow, hmap_node, &lflows) { @@ -11339,7 +11424,7 @@ build_lflows(struct northd_context *ctx, struct hmap *datapaths, uint8_t table = ovn_stage_get_table(lflow->stage); sbflow = sbrec_logical_flow_insert(ctx->ovnsb_txn); - sbrec_logical_flow_set_logical_datapath(sbflow, lflow->od->sb); + ovn_sb_set_lflow_logical_datapath_group(ctx, sbflow, &lflow->od); sbrec_logical_flow_set_pipeline(sbflow, pipeline); sbrec_logical_flow_set_table_id(sbflow, table); sbrec_logical_flow_set_priority(sbflow, lflow->priority); @@ -12914,12 +12999,19 @@ main(int argc, char *argv[]) ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_logical_flow); add_column_noalert(ovnsb_idl_loop.idl, &sbrec_logical_flow_col_logical_datapath); + add_column_noalert(ovnsb_idl_loop.idl, + &sbrec_logical_flow_col_logical_datapath_group); add_column_noalert(ovnsb_idl_loop.idl, &sbrec_logical_flow_col_pipeline); add_column_noalert(ovnsb_idl_loop.idl, &sbrec_logical_flow_col_table_id); add_column_noalert(ovnsb_idl_loop.idl, &sbrec_logical_flow_col_priority); add_column_noalert(ovnsb_idl_loop.idl, &sbrec_logical_flow_col_match); add_column_noalert(ovnsb_idl_loop.idl, &sbrec_logical_flow_col_actions); + ovsdb_idl_add_table(ovnsb_idl_loop.idl, + &sbrec_table_logical_datapath_group); + add_column_noalert(ovnsb_idl_loop.idl, + &sbrec_logical_datapath_group_col_datapaths); + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_multicast_group); add_column_noalert(ovnsb_idl_loop.idl, &sbrec_multicast_group_col_datapath); From patchwork Sat Nov 14 07:56:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Maximets X-Patchwork-Id: 1400235 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=ovn.org 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 4CY73M72Cbz9sRK for ; Sat, 14 Nov 2020 18:57:19 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 66D1A876E9; Sat, 14 Nov 2020 07:57:18 +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 C4F8krjBGh6I; Sat, 14 Nov 2020 07:57:13 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id EE6FC876DB; Sat, 14 Nov 2020 07:57:11 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id D3312C163C; Sat, 14 Nov 2020 07:57:11 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 3B7F4C163C for ; Sat, 14 Nov 2020 07:57:10 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 2A406879B5 for ; Sat, 14 Nov 2020 07:57:10 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 2NaexxuI21Cn for ; Sat, 14 Nov 2020 07:57:09 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by hemlock.osuosl.org (Postfix) with ESMTPS id A917A87984 for ; Sat, 14 Nov 2020 07:57:08 +0000 (UTC) X-Originating-IP: 78.45.89.65 Received: from im-t490s.redhat.com (ip-78-45-89-65.net.upcbroadband.cz [78.45.89.65]) (Authenticated sender: i.maximets@ovn.org) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id BAF36FF806; Sat, 14 Nov 2020 07:57:06 +0000 (UTC) From: Ilya Maximets To: ovs-dev@openvswitch.org Date: Sat, 14 Nov 2020 08:56:51 +0100 Message-Id: <20201114075653.9142-5-i.maximets@ovn.org> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20201114075653.9142-1-i.maximets@ovn.org> References: <20201114075653.9142-1-i.maximets@ovn.org> MIME-Version: 1.0 Cc: Ilya Maximets Subject: [ovs-dev] [PATCH ovn 4/6] controller: Add support for Logical Datapath Groups. 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" Signed-off-by: Ilya Maximets --- controller/lflow.c | 105 +++++++++++++++++++++++------------- controller/lflow.h | 1 - controller/ovn-controller.c | 23 ++------ 3 files changed, 73 insertions(+), 56 deletions(-) diff --git a/controller/lflow.c b/controller/lflow.c index f631679c3..385fd4876 100644 --- a/controller/lflow.c +++ b/controller/lflow.c @@ -666,6 +666,7 @@ update_conj_id_ofs(uint32_t *conj_id_ofs, uint32_t n_conjs) static void add_matches_to_flow_table(const struct sbrec_logical_flow *lflow, + const struct sbrec_datapath_binding *dp, struct hmap *matches, size_t conj_id_ofs, uint8_t ptable, uint8_t output_ptable, struct ofpbuf *ovnacts, @@ -676,7 +677,7 @@ add_matches_to_flow_table(const struct sbrec_logical_flow *lflow, .sbrec_multicast_group_by_name_datapath = l_ctx_in->sbrec_multicast_group_by_name_datapath, .sbrec_port_binding_by_name = l_ctx_in->sbrec_port_binding_by_name, - .dp = lflow->logical_datapath + .dp = dp, }; /* Encode OVN logical actions into OpenFlow. */ @@ -686,7 +687,7 @@ add_matches_to_flow_table(const struct sbrec_logical_flow *lflow, .lookup_port = lookup_port_cb, .tunnel_ofport = tunnel_ofport_cb, .aux = &aux, - .is_switch = datapath_is_switch(lflow->logical_datapath), + .is_switch = datapath_is_switch(dp), .group_table = l_ctx_out->group_table, .meter_table = l_ctx_out->meter_table, .lflow_uuid = lflow->header_.uuid, @@ -702,17 +703,16 @@ add_matches_to_flow_table(const struct sbrec_logical_flow *lflow, struct expr_match *m; HMAP_FOR_EACH (m, hmap_node, matches) { - match_set_metadata(&m->match, - htonll(lflow->logical_datapath->tunnel_key)); + match_set_metadata(&m->match, htonll(dp->tunnel_key)); if (m->match.wc.masks.conj_id) { m->match.flow.conj_id += conj_id_ofs; } - if (datapath_is_switch(lflow->logical_datapath)) { + if (datapath_is_switch(dp)) { unsigned int reg_index = (ingress ? MFF_LOG_INPORT : MFF_LOG_OUTPORT) - MFF_REG0; int64_t port_id = m->match.flow.regs[reg_index]; if (port_id) { - int64_t dp_id = lflow->logical_datapath->tunnel_key; + int64_t dp_id = dp->tunnel_key; char buf[16]; get_unique_lport_key(dp_id, port_id, buf, sizeof(buf)); lflow_resource_add(l_ctx_out->lfrr, REF_TYPE_PORTBINDING, buf, @@ -761,6 +761,7 @@ add_matches_to_flow_table(const struct sbrec_logical_flow *lflow, */ static struct expr * convert_match_to_expr(const struct sbrec_logical_flow *lflow, + const struct sbrec_datapath_binding *dp, struct expr *prereqs, const struct shash *addr_sets, const struct shash *port_groups, @@ -773,8 +774,7 @@ convert_match_to_expr(const struct sbrec_logical_flow *lflow, struct expr *e = expr_parse_string(lflow->match, &symtab, addr_sets, port_groups, &addr_sets_ref, - &port_groups_ref, - lflow->logical_datapath->tunnel_key, + &port_groups_ref, dp->tunnel_key, &error); const char *addr_set_name; SSET_FOR_EACH (addr_set_name, &addr_sets_ref) { @@ -812,23 +812,18 @@ convert_match_to_expr(const struct sbrec_logical_flow *lflow, } static bool -consider_logical_flow(const struct sbrec_logical_flow *lflow, - struct hmap *dhcp_opts, struct hmap *dhcpv6_opts, - struct hmap *nd_ra_opts, - struct controller_event_options *controller_event_opts, - struct lflow_ctx_in *l_ctx_in, - struct lflow_ctx_out *l_ctx_out) +consider_logical_flow__(const struct sbrec_logical_flow *lflow, + const struct sbrec_datapath_binding *dp, + struct hmap *dhcp_opts, struct hmap *dhcpv6_opts, + struct hmap *nd_ra_opts, + struct controller_event_options *controller_event_opts, + struct lflow_ctx_in *l_ctx_in, + struct lflow_ctx_out *l_ctx_out) { /* Determine translation of logical table IDs to physical table IDs. */ bool ingress = !strcmp(lflow->pipeline, "ingress"); - const struct sbrec_datapath_binding *ldp = lflow->logical_datapath; - if (!ldp) { - VLOG_DBG("lflow "UUID_FMT" has no datapath binding, skip", - UUID_ARGS(&lflow->header_.uuid)); - return true; - } - if (!get_local_datapath(l_ctx_in->local_datapaths, ldp->tunnel_key)) { + if (!get_local_datapath(l_ctx_in->local_datapaths, dp->tunnel_key)) { VLOG_DBG("lflow "UUID_FMT" is not for local datapath, skip", UUID_ARGS(&lflow->header_.uuid)); return true; @@ -877,7 +872,7 @@ consider_logical_flow(const struct sbrec_logical_flow *lflow, .sbrec_multicast_group_by_name_datapath = l_ctx_in->sbrec_multicast_group_by_name_datapath, .sbrec_port_binding_by_name = l_ctx_in->sbrec_port_binding_by_name, - .dp = lflow->logical_datapath + .dp = dp, }; struct condition_aux cond_aux = { .sbrec_port_binding_by_name = l_ctx_in->sbrec_port_binding_by_name, @@ -890,7 +885,7 @@ consider_logical_flow(const struct sbrec_logical_flow *lflow, struct expr *expr = NULL; if (!l_ctx_out->lflow_cache_map) { /* Caching is disabled. */ - expr = convert_match_to_expr(lflow, prereqs, l_ctx_in->addr_sets, + expr = convert_match_to_expr(lflow, dp, prereqs, l_ctx_in->addr_sets, l_ctx_in->port_groups, l_ctx_out->lfrr, NULL); if (!expr) { @@ -916,7 +911,7 @@ consider_logical_flow(const struct sbrec_logical_flow *lflow, return true; } - add_matches_to_flow_table(lflow, &matches, *l_ctx_out->conj_id_ofs, + add_matches_to_flow_table(lflow, dp, &matches, *l_ctx_out->conj_id_ofs, ptable, output_ptable, &ovnacts, ingress, l_ctx_in, l_ctx_out); @@ -933,7 +928,7 @@ consider_logical_flow(const struct sbrec_logical_flow *lflow, if (lc && lc->type == LCACHE_T_MATCHES) { /* 'matches' is cached. No need to do expr parsing. * Add matches to flow table and return. */ - add_matches_to_flow_table(lflow, lc->expr_matches, lc->conj_id_ofs, + add_matches_to_flow_table(lflow, dp, lc->expr_matches, lc->conj_id_ofs, ptable, output_ptable, &ovnacts, ingress, l_ctx_in, l_ctx_out); ovnacts_free(ovnacts.data, ovnacts.size); @@ -953,7 +948,7 @@ consider_logical_flow(const struct sbrec_logical_flow *lflow, bool pg_addr_set_ref = false; if (!expr) { - expr = convert_match_to_expr(lflow, prereqs, l_ctx_in->addr_sets, + expr = convert_match_to_expr(lflow, dp, prereqs, l_ctx_in->addr_sets, l_ctx_in->port_groups, l_ctx_out->lfrr, &pg_addr_set_ref); if (!expr) { @@ -1011,7 +1006,7 @@ consider_logical_flow(const struct sbrec_logical_flow *lflow, } /* Encode OVN logical actions into OpenFlow. */ - add_matches_to_flow_table(lflow, matches, lc->conj_id_ofs, + add_matches_to_flow_table(lflow, dp, matches, lc->conj_id_ofs, ptable, output_ptable, &ovnacts, ingress, l_ctx_in, l_ctx_out); ovnacts_free(ovnacts.data, ovnacts.size); @@ -1033,6 +1028,35 @@ consider_logical_flow(const struct sbrec_logical_flow *lflow, return true; } +static bool +consider_logical_flow(const struct sbrec_logical_flow *lflow, + struct hmap *dhcp_opts, struct hmap *dhcpv6_opts, + struct hmap *nd_ra_opts, + struct controller_event_options *controller_event_opts, + struct lflow_ctx_in *l_ctx_in, + struct lflow_ctx_out *l_ctx_out) +{ + struct sbrec_logical_datapath_group *dp_group + = lflow->logical_datapath_group; + bool ret = true; + + if (!dp_group) { + VLOG_DBG("lflow "UUID_FMT" has no datapath binding, skip", + UUID_ARGS(&lflow->header_.uuid)); + return true; + } + + for (size_t i = 0; i < dp_group->n_datapaths; i++) { + if (!consider_logical_flow__(lflow, dp_group->datapaths[i], + dhcp_opts, dhcpv6_opts, nd_ra_opts, + controller_event_opts, + l_ctx_in, l_ctx_out)) { + ret = false; + } + } + return ret; +} + static void put_load(const uint8_t *data, size_t len, enum mf_field_id dst, int ofs, int n_bits, @@ -1235,22 +1259,29 @@ lflow_add_flows_for_datapath(const struct sbrec_datapath_binding *dp, struct controller_event_options controller_event_opts; controller_event_opts_init(&controller_event_opts); - struct sbrec_logical_flow *lf_row = sbrec_logical_flow_index_init_row( - l_ctx_in->sbrec_logical_flow_by_logical_datapath); - sbrec_logical_flow_index_set_logical_datapath(lf_row, dp); - const struct sbrec_logical_flow *lflow; - SBREC_LOGICAL_FLOW_FOR_EACH_EQUAL ( - lflow, lf_row, l_ctx_in->sbrec_logical_flow_by_logical_datapath) { - if (!consider_logical_flow(lflow, &dhcp_opts, &dhcpv6_opts, - &nd_ra_opts, &controller_event_opts, - l_ctx_in, l_ctx_out)) { + SBREC_LOGICAL_FLOW_TABLE_FOR_EACH (lflow, l_ctx_in->logical_flow_table) { + struct sbrec_logical_datapath_group *dp_group + = lflow->logical_datapath_group; + bool found = false; + + if (dp_group) { + for (size_t i = 0; i < dp_group->n_datapaths; i++) { + if (dp_group->datapaths[i] == dp) { + found = true; + break; + } + } + } + if (found && !consider_logical_flow__(lflow, dp, &dhcp_opts, + &dhcpv6_opts, &nd_ra_opts, + &controller_event_opts, + l_ctx_in, l_ctx_out)) { handled = false; l_ctx_out->conj_id_overflow = true; break; } } - sbrec_logical_flow_index_destroy_row(lf_row); dhcp_opts_destroy(&dhcp_opts); dhcp_opts_destroy(&dhcpv6_opts); diff --git a/controller/lflow.h b/controller/lflow.h index 1251fb0f4..9baee7716 100644 --- a/controller/lflow.h +++ b/controller/lflow.h @@ -123,7 +123,6 @@ void lflow_resource_clear(struct lflow_resource_ref *); struct lflow_ctx_in { struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath; - struct ovsdb_idl_index *sbrec_logical_flow_by_logical_datapath; struct ovsdb_idl_index *sbrec_port_binding_by_name; const struct sbrec_dhcp_options_table *dhcp_options_table; const struct sbrec_dhcpv6_options_table *dhcpv6_options_table; diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c index a06cae3cc..aa20091b8 100644 --- a/controller/ovn-controller.c +++ b/controller/ovn-controller.c @@ -153,7 +153,7 @@ update_sb_monitors(struct ovsdb_idl *ovnsb_idl, * a VIF on a particular logical switch, we immediately know to monitor all * the connected logical routers and logical switches. */ struct ovsdb_idl_condition pb = OVSDB_IDL_CONDITION_INIT(&pb); - struct ovsdb_idl_condition lf = OVSDB_IDL_CONDITION_INIT(&lf); + struct ovsdb_idl_condition ldpg = OVSDB_IDL_CONDITION_INIT(&ldpg); struct ovsdb_idl_condition mb = OVSDB_IDL_CONDITION_INIT(&mb); struct ovsdb_idl_condition mg = OVSDB_IDL_CONDITION_INIT(&mg); struct ovsdb_idl_condition dns = OVSDB_IDL_CONDITION_INIT(&dns); @@ -164,7 +164,7 @@ update_sb_monitors(struct ovsdb_idl *ovnsb_idl, if (monitor_all) { ovsdb_idl_condition_add_clause_true(&pb); - ovsdb_idl_condition_add_clause_true(&lf); + ovsdb_idl_condition_add_clause_true(&ldpg); ovsdb_idl_condition_add_clause_true(&mb); ovsdb_idl_condition_add_clause_true(&mg); ovsdb_idl_condition_add_clause_true(&dns); @@ -226,8 +226,8 @@ update_sb_monitors(struct ovsdb_idl *ovnsb_idl, struct uuid *uuid = CONST_CAST(struct uuid *, &ld->datapath->header_.uuid); sbrec_port_binding_add_clause_datapath(&pb, OVSDB_F_EQ, uuid); - sbrec_logical_flow_add_clause_logical_datapath(&lf, OVSDB_F_EQ, - uuid); + sbrec_logical_datapath_group_add_clause_datapaths( + &ldpg, OVSDB_F_INCLUDES, &uuid, 1); sbrec_mac_binding_add_clause_datapath(&mb, OVSDB_F_EQ, uuid); sbrec_multicast_group_add_clause_datapath(&mg, OVSDB_F_EQ, uuid); sbrec_dns_add_clause_datapaths(&dns, OVSDB_F_INCLUDES, &uuid, 1); @@ -238,7 +238,7 @@ update_sb_monitors(struct ovsdb_idl *ovnsb_idl, out: sbrec_port_binding_set_condition(ovnsb_idl, &pb); - sbrec_logical_flow_set_condition(ovnsb_idl, &lf); + sbrec_logical_datapath_group_set_condition(ovnsb_idl, &ldpg); sbrec_mac_binding_set_condition(ovnsb_idl, &mb); sbrec_multicast_group_set_condition(ovnsb_idl, &mg); sbrec_dns_set_condition(ovnsb_idl, &dns); @@ -247,7 +247,6 @@ out: sbrec_igmp_group_set_condition(ovnsb_idl, &igmp); sbrec_chassis_private_set_condition(ovnsb_idl, &chprv); ovsdb_idl_condition_destroy(&pb); - ovsdb_idl_condition_destroy(&lf); ovsdb_idl_condition_destroy(&mb); ovsdb_idl_condition_destroy(&mg); ovsdb_idl_condition_destroy(&dns); @@ -1652,11 +1651,6 @@ static void init_lflow_ctx(struct engine_node *node, engine_get_input("SB_port_binding", node), "name"); - struct ovsdb_idl_index *sbrec_logical_flow_by_dp = - engine_ovsdb_node_get_index( - engine_get_input("SB_logical_flow", node), - "logical_datapath"); - struct ovsdb_idl_index *sbrec_mc_group_by_name_dp = engine_ovsdb_node_get_index( engine_get_input("SB_multicast_group", node), @@ -1704,8 +1698,6 @@ static void init_lflow_ctx(struct engine_node *node, l_ctx_in->sbrec_multicast_group_by_name_datapath = sbrec_mc_group_by_name_dp; - l_ctx_in->sbrec_logical_flow_by_logical_datapath = - sbrec_logical_flow_by_dp; l_ctx_in->sbrec_port_binding_by_name = sbrec_port_binding_by_name; l_ctx_in->dhcp_options_table = dhcp_table; l_ctx_in->dhcpv6_options_table = dhcpv6_table; @@ -2188,9 +2180,6 @@ main(int argc, char *argv[]) = chassis_private_index_create(ovnsb_idl_loop.idl); struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath = mcast_group_index_create(ovnsb_idl_loop.idl); - struct ovsdb_idl_index *sbrec_logical_flow_by_logical_datapath - = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, - &sbrec_logical_flow_col_logical_datapath); struct ovsdb_idl_index *sbrec_port_binding_by_name = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, &sbrec_port_binding_col_logical_port); @@ -2362,8 +2351,6 @@ main(int argc, char *argv[]) engine_ovsdb_node_add_index(&en_sb_chassis, "name", sbrec_chassis_by_name); engine_ovsdb_node_add_index(&en_sb_multicast_group, "name_datapath", sbrec_multicast_group_by_name_datapath); - engine_ovsdb_node_add_index(&en_sb_logical_flow, "logical_datapath", - sbrec_logical_flow_by_logical_datapath); engine_ovsdb_node_add_index(&en_sb_port_binding, "name", sbrec_port_binding_by_name); engine_ovsdb_node_add_index(&en_sb_port_binding, "key", From patchwork Sat Nov 14 07:56:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Maximets X-Patchwork-Id: 1400236 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.138; helo=whitealder.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CY73T0FpBz9sRK for ; Sat, 14 Nov 2020 18:57:24 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 2743887716; Sat, 14 Nov 2020 07:57:20 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id J4QLCJB2Nu4G; Sat, 14 Nov 2020 07:57:14 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by whitealder.osuosl.org (Postfix) with ESMTP id C87C7876B3; Sat, 14 Nov 2020 07:57:14 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id B36B8C0891; Sat, 14 Nov 2020 07:57:14 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id A015AC0800 for ; Sat, 14 Nov 2020 07:57:11 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 8E763879E3 for ; Sat, 14 Nov 2020 07:57:11 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id lFKyhGkoWhNq for ; Sat, 14 Nov 2020 07:57:10 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by hemlock.osuosl.org (Postfix) with ESMTPS id 5BEF887984 for ; Sat, 14 Nov 2020 07:57:10 +0000 (UTC) X-Originating-IP: 78.45.89.65 Received: from im-t490s.redhat.com (ip-78-45-89-65.net.upcbroadband.cz [78.45.89.65]) (Authenticated sender: i.maximets@ovn.org) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id 7208EFF804; Sat, 14 Nov 2020 07:57:08 +0000 (UTC) From: Ilya Maximets To: ovs-dev@openvswitch.org Date: Sat, 14 Nov 2020 08:56:52 +0100 Message-Id: <20201114075653.9142-6-i.maximets@ovn.org> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20201114075653.9142-1-i.maximets@ovn.org> References: <20201114075653.9142-1-i.maximets@ovn.org> MIME-Version: 1.0 Cc: Ilya Maximets Subject: [ovs-dev] [PATCH ovn 5/6] utilities: Add support for Logical Datapath Groups. 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" Signed-off-by: Ilya Maximets --- utilities/ovn-sbctl.c | 57 ++++++++++++++++++++++++++++++------------- utilities/ovn-trace.c | 35 ++++++++++++++++++-------- 2 files changed, 65 insertions(+), 27 deletions(-) diff --git a/utilities/ovn-sbctl.c b/utilities/ovn-sbctl.c index 85e448ec0..bd8c00918 100644 --- a/utilities/ovn-sbctl.c +++ b/utilities/ovn-sbctl.c @@ -520,7 +520,8 @@ pre_get_info(struct ctl_context *ctx) ovsdb_idl_add_column(ctx->idl, &sbrec_port_binding_col_chassis); ovsdb_idl_add_column(ctx->idl, &sbrec_port_binding_col_datapath); - ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_logical_datapath); + ovsdb_idl_add_column(ctx->idl, + &sbrec_logical_flow_col_logical_datapath_group); ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_pipeline); ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_actions); ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_priority); @@ -528,6 +529,9 @@ pre_get_info(struct ctl_context *ctx) ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_match); ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_external_ids); + ovsdb_idl_add_column(ctx->idl, + &sbrec_logical_datapath_group_col_datapaths); + ovsdb_idl_add_column(ctx->idl, &sbrec_datapath_binding_col_external_ids); ovsdb_idl_add_column(ctx->idl, &sbrec_ip_multicast_col_datapath); @@ -713,16 +717,10 @@ lflow_cmp(const void *a_, const void *b_) const struct sbrec_logical_flow *a = *ap; const struct sbrec_logical_flow *b = *bp; - const struct sbrec_datapath_binding *adb = a->logical_datapath; - const struct sbrec_datapath_binding *bdb = b->logical_datapath; - const char *a_name = smap_get_def(&adb->external_ids, "name", ""); - const char *b_name = smap_get_def(&bdb->external_ids, "name", ""); - int cmp = strcmp(a_name, b_name); - if (cmp) { - return cmp; - } + const struct sbrec_logical_datapath_group *adb = a->logical_datapath_group; + const struct sbrec_logical_datapath_group *bdb = b->logical_datapath_group; - cmp = uuid_compare_3way(&adb->header_.uuid, &bdb->header_.uuid); + int cmp = uuid_compare_3way(&adb->header_.uuid, &bdb->header_.uuid); if (cmp) { return cmp; } @@ -1009,6 +1007,21 @@ cmd_lflow_list_chassis(struct ctl_context *ctx, struct vconn *vconn, } } +static bool +datapath_group_contains_datapath(const struct sbrec_logical_datapath_group *g, + const struct sbrec_datapath_binding *dp) +{ + if (!g || !dp) { + return false; + } + for (size_t i = 0; i < g->n_datapaths; i++) { + if (g->datapaths[i] == dp) { + return true; + } + } + return false; +} + static void cmd_lflow_list(struct ctl_context *ctx) { @@ -1045,7 +1058,9 @@ cmd_lflow_list(struct ctl_context *ctx) size_t n_capacity = 0; const struct sbrec_logical_flow *lflow; SBREC_LOGICAL_FLOW_FOR_EACH (lflow, ctx->idl) { - if (datapath && lflow->logical_datapath != datapath) { + if (datapath + && !datapath_group_contains_datapath(lflow->logical_datapath_group, + datapath)) { continue; } @@ -1089,13 +1104,21 @@ cmd_lflow_list(struct ctl_context *ctx) /* Print a header line for this datapath or pipeline, if we haven't * already done so. */ if (!prev - || prev->logical_datapath != lflow->logical_datapath + || prev->logical_datapath_group != lflow->logical_datapath_group || strcmp(prev->pipeline, lflow->pipeline)) { - printf("Datapath: "); - print_datapath_name(lflow->logical_datapath); - printf(" ("UUID_FMT") Pipeline: %s\n", - UUID_ARGS(&lflow->logical_datapath->header_.uuid), - lflow->pipeline); + const struct sbrec_logical_datapath_group *g; + + printf("Datapaths: "); + g = lflow->logical_datapath_group; + for (size_t j = 0; j < g->n_datapaths; j++) { + if (j) { + printf(" "); + } + print_datapath_name(g->datapaths[j]); + printf(" ("UUID_FMT") Pipeline: %s\n", + UUID_ARGS(&g->datapaths[j]->header_.uuid), + lflow->pipeline); + } } /* Print the flow. */ diff --git a/utilities/ovn-trace.c b/utilities/ovn-trace.c index 29bf7a208..402a0ab71 100644 --- a/utilities/ovn-trace.c +++ b/utilities/ovn-trace.c @@ -874,18 +874,14 @@ ovntrace_make_names_friendly(const char *in) } static void -read_flows(void) +parse_lflow_for_datpath(const struct sbrec_logical_flow *sblf, + const struct sbrec_datapath_binding *sbdb) { - ovn_init_symtab(&symtab); - - const struct sbrec_logical_flow *sblf; - SBREC_LOGICAL_FLOW_FOR_EACH (sblf, ovnsb_idl) { - const struct sbrec_datapath_binding *sbdb = sblf->logical_datapath; struct ovntrace_datapath *dp = ovntrace_datapath_find_by_sb_uuid(&sbdb->header_.uuid); if (!dp) { VLOG_WARN("logical flow missing datapath"); - continue; + return; } char *error; @@ -897,7 +893,7 @@ read_flows(void) VLOG_WARN("%s: parsing expression failed (%s)", sblf->match, error); free(error); - continue; + return; } struct ovnact_parse_params pp = { @@ -919,7 +915,7 @@ read_flows(void) VLOG_WARN("%s: parsing actions failed (%s)", sblf->actions, error); free(error); expr_destroy(match); - continue; + return; } match = expr_combine(EXPR_T_AND, match, prereqs); @@ -930,7 +926,7 @@ read_flows(void) expr_destroy(match); ovnacts_free(ovnacts.data, ovnacts.size); ofpbuf_uninit(&ovnacts); - continue; + return; } if (match) { match = expr_simplify(match); @@ -960,6 +956,25 @@ read_flows(void) sizeof *dp->flows); } dp->flows[dp->n_flows++] = flow; +} + +static void +read_flows(void) +{ + ovn_init_symtab(&symtab); + + const struct sbrec_logical_flow *sblf; + SBREC_LOGICAL_FLOW_FOR_EACH (sblf, ovnsb_idl) { + const struct sbrec_logical_datapath_group *g; + + g = sblf->logical_datapath_group; + if (!g || !g->n_datapaths) { + VLOG_WARN("logical flow missing datapath group"); + continue; + } + for (size_t i = 0; i < g->n_datapaths; i++) { + parse_lflow_for_datpath(sblf, g->datapaths[i]); + } } const struct ovntrace_datapath *dp; From patchwork Sat Nov 14 07:56:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Maximets X-Patchwork-Id: 1400238 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.133; helo=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CY73j6rSWz9sRK for ; Sat, 14 Nov 2020 18:57:37 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 6AD3587A2C; Sat, 14 Nov 2020 07:57:35 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 9RHYUyl5xtf5; Sat, 14 Nov 2020 07:57:30 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id 9B90F87A33; Sat, 14 Nov 2020 07:57:28 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 7BFD7C1DD3; Sat, 14 Nov 2020 07:57:28 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id DEBC8C1DCD for ; Sat, 14 Nov 2020 07:57:27 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id ACC652E2A4 for ; Sat, 14 Nov 2020 07:57:27 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id EqZ1CWtiMzRN for ; Sat, 14 Nov 2020 07:57:20 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by silver.osuosl.org (Postfix) with ESMTPS id 3D48320466 for ; Sat, 14 Nov 2020 07:57:12 +0000 (UTC) X-Originating-IP: 78.45.89.65 Received: from im-t490s.redhat.com (ip-78-45-89-65.net.upcbroadband.cz [78.45.89.65]) (Authenticated sender: i.maximets@ovn.org) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id 40D5CFF805; Sat, 14 Nov 2020 07:57:10 +0000 (UTC) From: Ilya Maximets To: ovs-dev@openvswitch.org Date: Sat, 14 Nov 2020 08:56:53 +0100 Message-Id: <20201114075653.9142-7-i.maximets@ovn.org> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20201114075653.9142-1-i.maximets@ovn.org> References: <20201114075653.9142-1-i.maximets@ovn.org> MIME-Version: 1.0 Cc: Ilya Maximets Subject: [ovs-dev] [PATCH ovn 6/6] northd: Use same Logical Datapath Group for different flows. 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" This significantly reduces space wasted on storing duplicated datapath groups. Signed-off-by: Ilya Maximets --- northd/ovn-northd.c | 102 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 88 insertions(+), 14 deletions(-) diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index 782a539dc..a08b709fd 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -11315,12 +11315,29 @@ build_lswitch_and_lrouter_flows(struct hmap *datapaths, struct hmap *ports, build_lrouter_flows(datapaths, ports, lflows, meter_groups, lbs); } +struct ovn_dp_group { + struct hmapx map; + struct sbrec_logical_datapath_group *dp_group; + struct hmap_node node; +}; -static void -ovn_sb_set_lflow_logical_datapath_group( - struct northd_context *ctx, - const struct sbrec_logical_flow *sbflow, - const struct hmapx *od) +static struct ovn_dp_group * +ovn_dp_group_find(const struct hmap *dp_groups, + const struct hmapx *od, uint32_t hash) +{ + struct ovn_dp_group *dpg; + + HMAP_FOR_EACH_WITH_HASH (dpg, node, hash, dp_groups) { + if (hmapx_equals(&dpg->map, od)) { + return dpg; + } + } + return NULL; +} + +static struct sbrec_logical_datapath_group * +ovn_sb_insert_logical_datapath_group(struct northd_context *ctx, + const struct hmapx *od) { struct sbrec_logical_datapath_group *dp_group; const struct sbrec_datapath_binding **sb; @@ -11335,7 +11352,26 @@ ovn_sb_set_lflow_logical_datapath_group( sbrec_logical_datapath_group_set_datapaths( dp_group, (struct sbrec_datapath_binding **) sb, n); free(sb); - sbrec_logical_flow_set_logical_datapath_group(sbflow, dp_group); + + return dp_group; +} + +static void +ovn_sb_set_lflow_logical_datapath_group( + struct northd_context *ctx, + struct hmap *dp_groups, + const struct sbrec_logical_flow *sbflow, + const struct hmapx *od) +{ + struct ovn_dp_group *dpg; + + dpg = ovn_dp_group_find(dp_groups, od, hash_int(hmapx_count(od), 0)); + ovs_assert(dpg != NULL); + + if (!dpg->dp_group) { + dpg->dp_group = ovn_sb_insert_logical_datapath_group(ctx, &dpg->map); + } + sbrec_logical_flow_set_logical_datapath_group(sbflow, dpg->dp_group); } /* Updates the Logical_Flow and Multicast_Group tables in the OVN_SB database, @@ -11353,7 +11389,24 @@ build_lflows(struct northd_context *ctx, struct hmap *datapaths, port_groups, &lflows, mcgroups, igmp_groups, meter_groups, lbs); + /* Collecting all unique datapath groups. */ + struct hmap dp_groups = HMAP_INITIALIZER(&dp_groups); + struct ovn_lflow *lflow; + HMAP_FOR_EACH (lflow, hmap_node, &lflows) { + uint32_t hash = hash_int(hmapx_count(&lflow->od), 0); + struct ovn_dp_group *dpg; + + dpg = ovn_dp_group_find(&dp_groups, &lflow->od, hash); + if (!dpg) { + dpg = xzalloc(sizeof *dpg); + hmapx_clone(&dpg->map, &lflow->od); + hmap_insert(&dp_groups, &dpg->node, hash); + } + } + /* Push changes to the Logical_Flow table to database. */ + struct hmapx orphaned_dp_groups = HMAPX_INITIALIZER(&orphaned_dp_groups); + struct hmapx kept_dp_groups = HMAPX_INITIALIZER(&kept_dp_groups); const struct sbrec_logical_flow *sbflow, *next_sbflow; SBREC_LOGICAL_FLOW_FOR_EACH_SAFE (sbflow, next_sbflow, ctx->ovnsb_idl) { struct sbrec_logical_datapath_group *dp_group @@ -11376,7 +11429,7 @@ build_lflows(struct northd_context *ctx, struct hmap *datapaths, if (!n_valid_datapaths) { /* This lflow has no valid logical datapaths. */ - sbrec_logical_datapath_group_delete(dp_group); + hmapx_add(&orphaned_dp_groups, dp_group); sbrec_logical_flow_delete(sbflow); free(od); continue; @@ -11384,10 +11437,10 @@ build_lflows(struct northd_context *ctx, struct hmap *datapaths, enum ovn_pipeline pipeline = !strcmp(sbflow->pipeline, "ingress") ? P_IN : P_OUT; - struct ovn_lflow *lflow = ovn_lflow_find( + + lflow = ovn_lflow_find( &lflows, ovn_stage_build(dp_type, pipeline, sbflow->table_id), sbflow->priority, sbflow->match, sbflow->actions, sbflow->hash); - if (lflow) { /* This is a valid lflow. Checking if the datapath group needs * updates. */ @@ -11406,25 +11459,39 @@ build_lflows(struct northd_context *ctx, struct hmap *datapaths, if (update_datapath_group) { /* Re-creating datapath group since there are changes. */ - sbrec_logical_datapath_group_delete(dp_group); - ovn_sb_set_lflow_logical_datapath_group(ctx, + hmapx_add(&orphaned_dp_groups, dp_group); + ovn_sb_set_lflow_logical_datapath_group(ctx, &dp_groups, sbflow, &lflow->od); + } else { + hmapx_add(&kept_dp_groups, dp_group); } /* This lflow updated. Not needed anymore. */ ovn_lflow_destroy(&lflows, lflow); } else { - sbrec_logical_datapath_group_delete(dp_group); + hmapx_add(&orphaned_dp_groups, dp_group); sbrec_logical_flow_delete(sbflow); } free(od); } - struct ovn_lflow *lflow, *next_lflow; + + /* Remove all orphaned datapath groups, i.e. all groups without lflows. */ + const struct hmapx_node *node; + HMAPX_FOR_EACH (node, &orphaned_dp_groups) { + if (!hmapx_contains(&kept_dp_groups, node->data)) { + sbrec_logical_datapath_group_delete(node->data); + } + } + hmapx_destroy(&orphaned_dp_groups); + hmapx_destroy(&kept_dp_groups); + + struct ovn_lflow *next_lflow; HMAP_FOR_EACH_SAFE (lflow, next_lflow, hmap_node, &lflows) { const char *pipeline = ovn_stage_get_pipeline_name(lflow->stage); uint8_t table = ovn_stage_get_table(lflow->stage); sbflow = sbrec_logical_flow_insert(ctx->ovnsb_txn); - ovn_sb_set_lflow_logical_datapath_group(ctx, sbflow, &lflow->od); + ovn_sb_set_lflow_logical_datapath_group(ctx, &dp_groups, + sbflow, &lflow->od); sbrec_logical_flow_set_pipeline(sbflow, pipeline); sbrec_logical_flow_set_table_id(sbflow, table); sbrec_logical_flow_set_priority(sbflow, lflow->priority); @@ -11456,6 +11523,13 @@ build_lflows(struct northd_context *ctx, struct hmap *datapaths, } hmap_destroy(&lflows); + struct ovn_dp_group *dpg; + HMAP_FOR_EACH_POP (dpg, node, &dp_groups) { + hmapx_destroy(&dpg->map); + free(dpg); + } + hmap_destroy(&dp_groups); + /* Push changes to the Multicast_Group table to database. */ const struct sbrec_multicast_group *sbmc, *next_sbmc; SBREC_MULTICAST_GROUP_FOR_EACH_SAFE (sbmc, next_sbmc, ctx->ovnsb_idl) {