From patchwork Mon Aug 13 17:48:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 957072 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="SxI13yWx"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41q3BP4xm8z9sBD for ; Tue, 14 Aug 2018 03:49:01 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 8B3DACED; Mon, 13 Aug 2018 17:48:32 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id BFFF29D7 for ; Mon, 13 Aug 2018 17:48:30 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f196.google.com (mail-pg1-f196.google.com [209.85.215.196]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 87A58765 for ; Mon, 13 Aug 2018 17:48:30 +0000 (UTC) Received: by mail-pg1-f196.google.com with SMTP id x5-v6so7852422pgp.7 for ; Mon, 13 Aug 2018 10:48:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=43RQF4wb5guKu82Dup2HvEmJ8Drl2SWixK3SBZFJZwM=; b=SxI13yWx5HOJRV6IbDwsBIaW32FyXn2pha0WFt0g+s7ozjE1twlEWUy6pwnAQa2GBD d50AcRBOuBJsryyZCqUbhsQ/Hr4bW+sv/6ztvOFffBmNphQiWD4ToqJoTsb6ZxQhCqkQ inKZiTixSJ2rCwwWPlNnyBknEyvqY4F9KE5uAFMBPsFA7B/YEAtOIEUDChE0N6JpYD5f rWt9Zq7qHkUVI8huFCJc6H4tX0wTYZkgsmGVQr3tzznj7/+RmcDgmOf+3yV+HTSFYb9w Vwdjv5hqX8ilQ9JW6HcSynOOJp3f9VGX7kcURqEPEebn74DfiDPE8KuqjywDWvTSQzyR RiBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=43RQF4wb5guKu82Dup2HvEmJ8Drl2SWixK3SBZFJZwM=; b=PhtTeOs0/59wHwpYdUbXry742CsHtZeVBykryzuM5DJVIHqpVgwhllKLTeoBI96PWs sie6e2cVQKlhcosB2AbLoTHdZaulo5NXvItnfbSASTPByedKBJQx2bATWjl9YroiWAKT RZqT+AYg9N88p9PkXXSS1caMd/xlp7w17Flr01enYs1xit4MW4DJhhgjciWM3wgj0eXm +t1qHaQxhni7OqY1obzOUJQAwTwh3lr1tpLu5SYstYl3kY2GfI3oxCubFKB1X46Dn+YR p8BhiMlXKL5JEOvq9XR5OTSNsqHZ3N/toSltl2WpW7DEOuLiBNGthjcCrf0S1V4Ry/d4 1uwQ== X-Gm-Message-State: AOUpUlFeAmRmTW6BtDo0f+zqlWcHcIz7DwXG3qjST4e/Tg5KPoa6blYC mdXkk6QTva5gEfJSoQHhaTqDfInY X-Google-Smtp-Source: AA+uWPxt5SPdbyPSnOF562Z/q8zAallcKn3Ufw3Qc44u9Bb4liz7+/nO/bJILEhHEfnSdq8m3Aifjg== X-Received: by 2002:a62:5f82:: with SMTP id t124-v6mr20049859pfb.223.1534182510029; Mon, 13 Aug 2018 10:48:30 -0700 (PDT) Received: from localhost.localdomain.localdomain ([216.113.160.70]) by smtp.gmail.com with ESMTPSA id d22-v6sm38068664pfk.69.2018.08.13.10.48.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Aug 2018 10:48:29 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Mon, 13 Aug 2018 10:48:00 -0700 Message-Id: <1534182499-75914-2-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> References: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v5 01/20] ovsdb-idl.c: Remove a misleading comment for change tracking. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org The comment was added when the feature was introduced but what it described is not what is implemented, probably because of revisions after code reviews. Signed-off-by: Han Zhou --- lib/ovsdb-idl.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c index 40c29cb..b0ebe8c 100644 --- a/lib/ovsdb-idl.c +++ b/lib/ovsdb-idl.c @@ -2834,9 +2834,7 @@ ovsdb_idl_row_clear_arcs(struct ovsdb_idl_row *row, bool destroy_dsts) struct ovsdb_idl_arc *arc, *next; /* Delete all forward arcs. If 'destroy_dsts', destroy any orphaned rows - * that this causes to be unreferenced, if tracking is not enabled. - * If tracking is enabled, orphaned nodes are removed from hmap but not - * freed. + * that this causes to be unreferenced. */ LIST_FOR_EACH_SAFE (arc, next, src_node, &row->src_arcs) { ovs_list_remove(&arc->dst_node); From patchwork Mon Aug 13 17:48:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 957073 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Fttotw26"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41q3C842xhz9sBD for ; Tue, 14 Aug 2018 03:49:40 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 9E665D1E; Mon, 13 Aug 2018 17:48:33 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id DCFC4CE4 for ; Mon, 13 Aug 2018 17:48:31 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f42.google.com (mail-pl0-f42.google.com [209.85.160.42]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 73949765 for ; Mon, 13 Aug 2018 17:48:31 +0000 (UTC) Received: by mail-pl0-f42.google.com with SMTP id w14-v6so7192052plp.6 for ; Mon, 13 Aug 2018 10:48:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=TgHYJgDg/iJvrpBWorg1IYTQa7DReO5uOcJeSgGiqSk=; b=Fttotw26Inw722LgP4udw5TK4GvcojQK1/vjAG76MMsxAUloWSjWsZl4cjShJfNRBF 0y42YRDDgbJ9BIGsz9qS3uN+gz5yUL+hgikZ6YXc6JNjnSJ6TQ0MgRHsen3CkfRfS7RH o548VPdOYPyPemJ06G4XjFu2GtIYCzGQS2aea8bWjxKkaQ/xQhjCn4LN8lOArshHDNzn j2Kg9eYn5QChoFdlcEfqa6RsA2tromJ8Y5sgoc7U/beM8MhuQaXzoID71W0NveMOqCe9 fDl1u8EgI3sK1HfSVmTuMl6TlFGVHn2PCfddJDxubvCmhm55JurIwepX/vaPOYBHpLIa o0Jw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=TgHYJgDg/iJvrpBWorg1IYTQa7DReO5uOcJeSgGiqSk=; b=AsRuGnOMZc/q650OnRnIoGvDhV/SpRHJZvArfNaxBrmLIRd95rrDKtl6Npq9FvIEh4 UjO1YNjZGg4XFd23xiQFthlDGP6r6/KgtNw9Pkqs2gVxo36KzD5ZscZBpNoU0bfsSr4v edCdRI7r22cdXU18Skejd6p2Wgy6RcZgkULgVMQZ6NufX3R5izSj7RM1vOW9xE6BlE0n IMxyVED3n8jHVOq1BHdhXSNOrkII+hXVEJod0Gz1/AcFdlaYDpMnRXEkwNm3gcQRN/8N zYZcFGClsbIqSAR+4qr2hVOf8XrQ8P2EuBBo+7Rk5KUGA7nboBjnCsoAhezUe93+Bj4m lhBQ== X-Gm-Message-State: AOUpUlFp10TzTEyibNRq/c+41vYPRbhcNAP6u8CgP4e3+0r95jtPZ3h9 D9VwjsEBqGm72/OFOCQGkZoDWWp/ X-Google-Smtp-Source: AA+uWPyVRR6nvCqPradLrjSqUD26fB4rs98xr5ZE9DBMhZToMZf5X886N4/kBEccTbk8a6UK/JR3ZA== X-Received: by 2002:a17:902:8a97:: with SMTP id p23-v6mr17413285plo.21.1534182510849; Mon, 13 Aug 2018 10:48:30 -0700 (PDT) Received: from localhost.localdomain.localdomain ([216.113.160.70]) by smtp.gmail.com with ESMTPSA id d22-v6sm38068664pfk.69.2018.08.13.10.48.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Aug 2018 10:48:30 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Mon, 13 Aug 2018 10:48:01 -0700 Message-Id: <1534182499-75914-3-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> References: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v5 02/20] ovsdb-idl.c: Update conditions when handling change tracking list. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org There are places with the pattern: if (!ovs_list_is_empty(&row->track_node)) { ovs_list_remove(&row->track_node); } ovs_list_push_back(&row->table->track_list, &row->track_node); It seems to be trying to prevent double removing the node from a list, but actually it doesn't, and may be misleading. The function ovs_list_is_empty() returns true only if the node has been initialized with ovs_list_init(). If a node is deleted but not initialized, the check will return false and the above code will continue deleting it again. But if a node is already initialized, calling ovs_list_remove() is a no-op. So the check is not necessary and misleading. In fact there is already a double removal resulted by this code: the function ovsdb_idl_db_clear() removes the node but it then calls ovsdb_idl_row_destroy() immediately which removes the node again. It should not result in any real issue yet since the list was not changed so the second removal just assigns the pointers with same value. It is in fact not necessary to remove and then add back to the list, because the purpose of the change tracking is just to tell if a row is changed or not. So this patch removes the "check and remove" code before adding the node to a list, but instead, adding it to the list only if it is not in a list. This way it ensures the node is added to a list only once in one idl loop. (ovsdb_idl_db_track_clear() will be called in each iteration and the check ovs_list_is_empty() will return true at the first check in next iteration). Signed-off-by: Han Zhou --- lib/ovsdb-idl.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c index b0ebe8c..4b2bc21 100644 --- a/lib/ovsdb-idl.c +++ b/lib/ovsdb-idl.c @@ -557,10 +557,6 @@ ovsdb_idl_db_clear(struct ovsdb_idl_db *db) /* No need to do anything with dst_arcs: some node has those arcs * as forward arcs and will destroy them itself. */ - if (!ovs_list_is_empty(&row->track_node)) { - ovs_list_remove(&row->track_node); - } - ovsdb_idl_row_destroy(row); } } @@ -2366,11 +2362,10 @@ ovsdb_idl_row_change__(struct ovsdb_idl_row *row, const struct json *row_json, = row->table->change_seqno[change] = row->table->db->change_seqno + 1; if (table->modes[column_idx] & OVSDB_IDL_TRACK) { - if (!ovs_list_is_empty(&row->track_node)) { - ovs_list_remove(&row->track_node); + if (ovs_list_is_empty(&row->track_node)) { + ovs_list_push_back(&row->table->track_list, + &row->track_node); } - ovs_list_push_back(&row->table->track_list, - &row->track_node); if (!row->updated) { row->updated = bitmap_allocate(class->n_columns); } @@ -2912,10 +2907,9 @@ ovsdb_idl_row_destroy(struct ovsdb_idl_row *row) = row->table->change_seqno[OVSDB_IDL_CHANGE_DELETE] = row->table->db->change_seqno + 1; } - if (!ovs_list_is_empty(&row->track_node)) { - ovs_list_remove(&row->track_node); + if (ovs_list_is_empty(&row->track_node)) { + ovs_list_push_back(&row->table->track_list, &row->track_node); } - ovs_list_push_back(&row->table->track_list, &row->track_node); } } From patchwork Mon Aug 13 17:48:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 957074 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="WLiklkH0"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41q3Cm4YQyz9sBD for ; Tue, 14 Aug 2018 03:50:12 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 59B7AD60; Mon, 13 Aug 2018 17:48:34 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 753A1CE4 for ; Mon, 13 Aug 2018 17:48:32 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f68.google.com (mail-pl0-f68.google.com [209.85.160.68]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 27F1F765 for ; Mon, 13 Aug 2018 17:48:32 +0000 (UTC) Received: by mail-pl0-f68.google.com with SMTP id j8-v6so7187216pll.12 for ; Mon, 13 Aug 2018 10:48:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=zw4EuHXpJQ3XMr5/+QXCBbxUkGEtMDD2krHedXhR/Vo=; b=WLiklkH0Ctsp5wuCpKCHwAeqHpPjSpNcNSa7lg37HIDHo4hU4NyapE33sfvt+MDSmU YsVwlvU7IpFR+fcwIC7aMyEz4SWt7tifBW3M8raQMCn40rCzVzSSmz/Xe3oDnpzqz0iJ 7s8dq6OYBBDQWNxO3pK7Ubv66oWMSKHMCyJ/95Dq2FkKz0xOM4P/MKkol1MaLeJQT6/8 xgsBCUwqY7kKfWQnaKvehzpJQ5mgivVZApGXjNtrYZp3lFUfmRpDQwR5vhUJD/M2R0WE eOnzqICVl11FLQh6LticOCk7yu7ArfCwd8GDR5XkyxlW0NJ2FOdF0a3NQHmWygjmbWqs Nytw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=zw4EuHXpJQ3XMr5/+QXCBbxUkGEtMDD2krHedXhR/Vo=; b=t4PP4bftXtDUH5Qzwpj9qany4QVRfNgGIxP1/6/iu23/iIV2ik/TO0bpsy99/d1+Q+ b17nWz5ljX/ZDc9F7vpyclF9RmiF9qzYLMxPwkUtIzr4OBBhpEk6pmAcSl5KHNobh8eG TwNg0EsHZN5mirK0XQnriCLAH9FESTv39cERuw2gcmylIt7yLfunR5I0X3MfV0wQlJ4u IE5meR8d3U/tvDKElRCD3hoBVGUJy67yQSzCYM0rAmeCQ5A2/pNs29dC3psOmxd4zGr0 gMZfNBCflGhQws5jfxfBfbO9tgNlH0LZU3LlWFfMlmeWKuwDPUDWr53E1rCUkxH/3lbm XM6g== X-Gm-Message-State: AOUpUlFNMf67cKxuuCRv0huvxjZjTqpBFDI7DgM+LZ2FwOSfYAAnkZV2 CsLS2AStuCwDCwfCKK1BYRJug/dF X-Google-Smtp-Source: AA+uWPwGNdCHMPfmRyxuBzo0VcqFTUBSoOgM/KxKH65lLo/3xSOhzlzL0GyvETyDCCkH0WvbrQX24Q== X-Received: by 2002:a17:902:b28:: with SMTP id 37-v6mr17335136plq.337.1534182511520; Mon, 13 Aug 2018 10:48:31 -0700 (PDT) Received: from localhost.localdomain.localdomain ([216.113.160.70]) by smtp.gmail.com with ESMTPSA id d22-v6sm38068664pfk.69.2018.08.13.10.48.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Aug 2018 10:48:31 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Mon, 13 Aug 2018 10:48:02 -0700 Message-Id: <1534182499-75914-4-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> References: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v5 03/20] ovsdb-idlc.in: Support more interfaces for passing pointers of individual tables. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org This is a follow-up patch for commit 0eb1e37c, to add more interfaces that supports passing around pointers of individual tables, which will be used in incremental processing. Signed-off-by: Han Zhou --- ovsdb/ovsdb-idlc.in | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/ovsdb/ovsdb-idlc.in b/ovsdb/ovsdb-idlc.in index ee655f7..1c9483c 100755 --- a/ovsdb/ovsdb-idlc.in +++ b/ovsdb/ovsdb-idlc.in @@ -251,6 +251,7 @@ const struct %(s)s *%(s)s_table_first(const struct %(s)s_table *); (ROW) = (NEXT)) const struct %(s)s *%(s)s_get_for_uuid(const struct ovsdb_idl *, const struct uuid *); +const struct %(s)s *%(s)s_table_get_for_uuid(const struct %(s)s_table *, const struct uuid *); const struct %(s)s *%(s)s_first(const struct ovsdb_idl *); const struct %(s)s *%(s)s_next(const struct %(s)s *); #define %(S)s_FOR_EACH(ROW, IDL) \\ @@ -271,6 +272,13 @@ const struct %(s)s *%(s)s_track_get_next(const struct %(s)s *); (ROW); \\ (ROW) = %(s)s_track_get_next(ROW)) +const struct %(s)s *%(s)s_table_track_get_first(const struct %(s)s_table *); +#define %(S)s_TABLE_FOR_EACH_TRACKED(ROW, TABLE) \\ + for ((ROW) = %(s)s_table_track_get_first(TABLE); \\ + (ROW); \\ + (ROW) = %(s)s_track_get_next(ROW)) + + /* Returns true if 'row' was inserted since the last change tracking reset. */ static inline bool %(s)s_is_new(const struct %(s)s *row) { @@ -479,6 +487,14 @@ const struct %(s)s * const struct ovsdb_idl *idl = (const struct ovsdb_idl *) table; return %(s)s_first(idl); } + + +const struct %(s)s * +%(s)s_table_track_get_first(const struct %(s)s_table *table) +{ + const struct ovsdb_idl *idl = (const struct ovsdb_idl *) table; + return %(s)s_track_get_first(idl); +} ''' % {'s': structName}) # Parse functions. @@ -655,6 +671,15 @@ const struct %(s)s * return %(s)s_cast(ovsdb_idl_get_row_for_uuid(idl, &%(p)stable_%(tl)s, uuid)); } +/* Searches table "%(t)s" for a row with UUID 'uuid'. Returns + * a pointer to the row if there is one, otherwise a null pointer. */ +const struct %(s)s * +%(s)s_table_get_for_uuid(const struct %(s)s_table *table, const struct uuid *uuid) +{ + const struct ovsdb_idl *idl = (const struct ovsdb_idl *) table; + return %(s)s_get_for_uuid(idl, uuid); +} + /* Returns a row in table "%(t)s" in 'idl', or a null pointer if that * table is empty. * From patchwork Mon Aug 13 17:48:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 957075 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Rw7K6Fn5"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41q3DN6F16z9sBD for ; Tue, 14 Aug 2018 03:50:44 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 3B681CE9; Mon, 13 Aug 2018 17:48:35 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id F22A9C7F for ; Mon, 13 Aug 2018 17:48:32 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f196.google.com (mail-pg1-f196.google.com [209.85.215.196]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id B0B3C788 for ; Mon, 13 Aug 2018 17:48:32 +0000 (UTC) Received: by mail-pg1-f196.google.com with SMTP id f14-v6so7840500pgv.13 for ; Mon, 13 Aug 2018 10:48:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=7379do3I5uxmfAuTun3HZOEFgxUpCk2i1uhlKbXMEK4=; b=Rw7K6Fn5LY/wLTKGmWl66Uuysxf12Z1w9WjLRXRRsgY2Qo/x2ouMNdGsyq8n3HWaIv SrSaQInAocPxtVAv+akG5nHhXS5oPvMJSSLhl5+vboiJjf7tdZ7o1Rpmh1LFVwk0TgiX ny3au5BDx4mtY/t04IyFnbpqISunyTcZcE0d+NBZRPt/dqdMLysm+VrOhM2tg9I9SqxJ oxEW1fmBZNos28pJFPdVT7PxU1t8EEYbqc2OXcDsbxVwSZCdzLpy5qTqI7VPdHYD+Z4X KZK4LTX5QQSRjG5d1LfTRtsGEymLhCF5FDw/6RQgkmOHkSPSX8MCeZbTxqXY23d/G2jR /Bfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=7379do3I5uxmfAuTun3HZOEFgxUpCk2i1uhlKbXMEK4=; b=Jt1jFC+7ZWjPCEOPxhlXwR73eZpZEWgpyD45Swm+n2wluOnWW3bgQnccq4GfUztPDo VMeRfaqJrHvrcg/vi/m4EMcC4sswNdoxJPNMFLWIh8UxntVpoFdr+UU/j3bPGG0PPtUK xGfR6T1hnRFossyKcxyjfofGSNW5TuIY1addML5OfjpAu+2Fu5e9iI6LFzqYkq9yMfg7 ep0nBztYwt2DSluR7hJYPaL0Vii3FFTNf+vFLVUczbaC8SvwCPN7ejadUVNsMr+x+KU/ GN7RxNRaxMjBVRyCiqDP4WIEhGOHqc4nUZOLlVHkxdlh1dB6J5EUsqMVAJ9LoWUHjyMm kvCQ== X-Gm-Message-State: AOUpUlEMHoDJwYzd8fSliuF6bd4xO8QHGHWsOffpQVktuFJCO3Gzh8Fi J9wDXBy+/IEvbDm8IT5rDiKtMxJR X-Google-Smtp-Source: AA+uWPwanIV44GChQnQ2ss+MUVcd6i8Aaduhl3RkaD6t16jjQnKlttsQxGpJ2+cmsYDNIWSG7TcKow== X-Received: by 2002:aa7:850b:: with SMTP id v11-v6mr19626696pfn.165.1534182512154; Mon, 13 Aug 2018 10:48:32 -0700 (PDT) Received: from localhost.localdomain.localdomain ([216.113.160.70]) by smtp.gmail.com with ESMTPSA id d22-v6sm38068664pfk.69.2018.08.13.10.48.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Aug 2018 10:48:31 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Mon, 13 Aug 2018 10:48:03 -0700 Message-Id: <1534182499-75914-5-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> References: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v5 04/20] ovsdb-idl.c: Track changes for table references. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org If a change of a row is tracked, make sure the rows that reference this row are also added in tracked changes, unless change tracking is not required for those rows. Signed-off-by: Han Zhou --- lib/ovsdb-idl.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c index 4b2bc21..468b3bf 100644 --- a/lib/ovsdb-idl.c +++ b/lib/ovsdb-idl.c @@ -2299,6 +2299,24 @@ ovsdb_idl_process_update2(struct ovsdb_idl_table *table, return true; } +/* Recursively add rows to tracked change lists for current row + * and the rows that reference this row. */ +static void +add_tracked_change_for_references(struct ovsdb_idl_row *row) +{ + if (ovs_list_is_empty(&row->track_node) && + ovsdb_idl_track_is_set(row->table)) { + ovs_list_push_back(&row->table->track_list, + &row->track_node); + + const struct ovsdb_idl_arc *arc; + LIST_FOR_EACH (arc, dst_node, &row->dst_arcs) { + add_tracked_change_for_references(arc->src); + } + } +} + + /* Returns true if a column with mode OVSDB_IDL_MODE_RW changed, false * otherwise. * @@ -2362,10 +2380,7 @@ ovsdb_idl_row_change__(struct ovsdb_idl_row *row, const struct json *row_json, = row->table->change_seqno[change] = row->table->db->change_seqno + 1; if (table->modes[column_idx] & OVSDB_IDL_TRACK) { - if (ovs_list_is_empty(&row->track_node)) { - ovs_list_push_back(&row->table->track_list, - &row->track_node); - } + add_tracked_change_for_references(row); if (!row->updated) { row->updated = bitmap_allocate(class->n_columns); } From patchwork Mon Aug 13 17:48:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 957076 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Jg14MgCO"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41q3Dw5dSvz9sBD for ; Tue, 14 Aug 2018 03:51:12 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 2E4BCD9D; Mon, 13 Aug 2018 17:48:37 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id B5340D6D for ; Mon, 13 Aug 2018 17:48:34 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pf1-f196.google.com (mail-pf1-f196.google.com [209.85.210.196]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 965047C4 for ; Mon, 13 Aug 2018 17:48:33 +0000 (UTC) Received: by mail-pf1-f196.google.com with SMTP id u24-v6so7981225pfn.13 for ; Mon, 13 Aug 2018 10:48:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=OTkczElc102QQg+DWJRBcS+p9RTR7cmZJQgUjTZf49M=; b=Jg14MgCOznlxAOBG5FtUTCmlZhTeJ+/3bE3ULiTW9bybFZHx9RH+wHNDjmY3bdIFV5 orVtx+PRWRyH1OYJqfocAbahNcB+6iXW+ZrtNdctRgwCaui3MSdgFgUunMnnC8aYP+un ZePS7e3fxaTPF+PepnjRM4iT3CIW0ksv9mFbpq3iUS0pHE3sZQ3Ilo4mtvx2LUx8dVkO SZWURb0n6Q06NKMlmB33+mWsA1ybYd20vWgfEFY4rR2AgUCQG0UgC44LMrWT5oRisVrd XQqVu9wlHDr6tOINQ5LkXqVtTZbd/NBOVaOq1JCNG4ikTgveiig5WfxXEr/La0kzg+fE Sx9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=OTkczElc102QQg+DWJRBcS+p9RTR7cmZJQgUjTZf49M=; b=MqZvZ4rquyh45vFRyKyEXlQBok+Hda5vZVDI+bCl6EeXSwWuscmHjCZpbJabbjDCCq CCRGaemwdQWAeDnx8Q33hpehoXAPIPT3D5u6Da3UD3d8BdJE/ZeN5r7OGJduGMutzH5H m+bj+cAUc1Ga/WRXtZjrL4H9Cus5q/9fC7X597KBVtZn7yj1d9v6h9cCZzMwVhpk/XAV d/8oQJVk8arxzkA5XHWulJ6/S311RvANpqQ2BSuOkfmQU82FO7t7uPwH4GkunrJDGyS3 DOM4CedYVLJYGHi+JIteVeN0hQutg2Doe6grcPSd68LA1501nI6U0RMFkmqKIqecXIbK qxdw== X-Gm-Message-State: AOUpUlGcOjFj9/BucPlnM9xhIdoxdeOQV9xMnUlLelxOslJ/wCyt8gJI Zi0wuwtZioJBEGzPf9lScko3NvAR X-Google-Smtp-Source: AA+uWPzpI3WPL1ei5F24pkf4fw6mqCrYBWdP4l/fdKraJyP3+UtNYvYJyY+r2rYXfsoCabfXNgo8wg== X-Received: by 2002:a62:5047:: with SMTP id e68-v6mr20237707pfb.157.1534182512860; Mon, 13 Aug 2018 10:48:32 -0700 (PDT) Received: from localhost.localdomain.localdomain ([216.113.160.70]) by smtp.gmail.com with ESMTPSA id d22-v6sm38068664pfk.69.2018.08.13.10.48.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Aug 2018 10:48:32 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Mon, 13 Aug 2018 10:48:04 -0700 Message-Id: <1534182499-75914-6-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> References: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v5 05/20] ovn-controller: Incremental processing engine X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org This patch implements the engine which will be used in future patches for ovn-controller incremental processing. Signed-off-by: Han Zhou --- ovn/lib/automake.mk | 4 +- ovn/lib/inc-proc-eng.c | 201 +++++++++++++++++++++++++++++++++++++++++ ovn/lib/inc-proc-eng.h | 240 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 444 insertions(+), 1 deletion(-) create mode 100644 ovn/lib/inc-proc-eng.c create mode 100644 ovn/lib/inc-proc-eng.h diff --git a/ovn/lib/automake.mk b/ovn/lib/automake.mk index 6178fc2..c1d37c5 100644 --- a/ovn/lib/automake.mk +++ b/ovn/lib/automake.mk @@ -17,7 +17,9 @@ ovn_lib_libovn_la_SOURCES = \ ovn/lib/ovn-util.c \ ovn/lib/ovn-util.h \ ovn/lib/logical-fields.c \ - ovn/lib/logical-fields.h + ovn/lib/logical-fields.h \ + ovn/lib/inc-proc-eng.c \ + ovn/lib/inc-proc-eng.h nodist_ovn_lib_libovn_la_SOURCES = \ ovn/lib/ovn-nb-idl.c \ ovn/lib/ovn-nb-idl.h \ diff --git a/ovn/lib/inc-proc-eng.c b/ovn/lib/inc-proc-eng.c new file mode 100644 index 0000000..1ddea1a --- /dev/null +++ b/ovn/lib/inc-proc-eng.c @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2018 eBay Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include +#include +#include + +#include "lib/util.h" +#include "openvswitch/dynamic-string.h" +#include "openvswitch/hmap.h" +#include "openvswitch/vlog.h" +#include "inc-proc-eng.h" + +VLOG_DEFINE_THIS_MODULE(inc_proc_eng); + +static bool engine_force_recompute = false; +static const struct engine_context *engine_context; + +void +engine_set_force_recompute(bool val) +{ + engine_force_recompute = val; +} + +const struct engine_context * +engine_get_context(void) +{ + return engine_context; +} + +void +engine_set_context(const struct engine_context *ctx) +{ + engine_context = ctx; +} + +void +engine_init(struct engine_node *node) +{ + for (size_t i = 0; i < node->n_inputs; i++) { + engine_init(node->inputs[i].node); + } + if (node->init) { + node->init(node); + } +} + +void +engine_cleanup(struct engine_node *node) +{ + for (size_t i = 0; i < node->n_inputs; i++) { + engine_cleanup(node->inputs[i].node); + } + if (node->cleanup) { + node->cleanup(node); + } +} + +struct engine_node * +engine_get_input(const char *input_name, struct engine_node *node) +{ + size_t i; + for (i = 0; i < node->n_inputs; i++) { + if (!strcmp(node->inputs[i].node->name, input_name)) { + return node->inputs[i].node; + } + } + OVS_NOT_REACHED(); + return NULL; +} + +void +engine_add_input(struct engine_node *node, struct engine_node *input, + bool (*change_handler)(struct engine_node *)) +{ + ovs_assert(node->n_inputs < ENGINE_MAX_INPUT); + node->inputs[node->n_inputs].node = input; + node->inputs[node->n_inputs].change_handler = change_handler; + node->n_inputs ++; +} + +struct ovsdb_idl_index * +engine_ovsdb_node_get_index(struct engine_node *node, const char *name) +{ + struct ed_type_ovsdb_table *ed = (struct ed_type_ovsdb_table *)node->data; + for (size_t i = 0; i < ed->n_indexes; i++) { + if (!strcmp(ed->indexes[i].name, name)) { + return ed->indexes[i].index; + } + } + OVS_NOT_REACHED(); + return NULL; +} + +void +engine_ovsdb_node_add_index(struct engine_node *node, const char *name, + struct ovsdb_idl_index *index) +{ + struct ed_type_ovsdb_table *ed = (struct ed_type_ovsdb_table *)node->data; + ovs_assert(ed->n_indexes < ENGINE_MAX_OVSDB_INDEX); + + ed->indexes[ed->n_indexes].name = name; + ed->indexes[ed->n_indexes].index = index; + ed->n_indexes ++; +} + +void +engine_run(struct engine_node *node, uint64_t run_id) +{ + if (node->run_id == run_id) { + return; + } + node->run_id = run_id; + + node->changed = false; + if (!node->n_inputs) { + node->run(node); + VLOG_DBG("node: %s, changed: %d", node->name, node->changed); + return; + } + + for (size_t i = 0; i < node->n_inputs; i++) { + engine_run(node->inputs[i].node, run_id); + } + + bool need_compute = false; + bool need_recompute = false; + + if (engine_force_recompute) { + need_recompute = true; + } else { + for (size_t i = 0; i < node->n_inputs; i++) { + if (node->inputs[i].node->changed) { + need_compute = true; + if (!node->inputs[i].change_handler) { + need_recompute = true; + break; + } + } + } + } + + if (need_recompute) { + VLOG_DBG("node: %s, recompute (%s)", node->name, + engine_force_recompute ? "forced" : "triggered"); + node->run(node); + } else if (need_compute) { + for (size_t i = 0; i < node->n_inputs; i++) { + if (node->inputs[i].node->changed) { + VLOG_DBG("node: %s, handle change for input %s", + node->name, node->inputs[i].node->name); + if (!node->inputs[i].change_handler(node)) { + VLOG_DBG("node: %s, can't handle change for input %s, " + "fall back to recompute", + node->name, node->inputs[i].node->name); + node->run(node); + break; + } + } + } + } + + VLOG_DBG("node: %s, changed: %d", node->name, node->changed); +} + +bool +engine_need_run(struct engine_node *node) +{ + size_t i; + + if (!node->n_inputs) { + node->run(node); + VLOG_DBG("input node: %s, changed: %d", node->name, node->changed); + return node->changed; + } + + for (i = 0; i < node->n_inputs; i++) { + if (engine_need_run(node->inputs[i].node)) { + return true; + } + } + + return false; +} diff --git a/ovn/lib/inc-proc-eng.h b/ovn/lib/inc-proc-eng.h new file mode 100644 index 0000000..df54061 --- /dev/null +++ b/ovn/lib/inc-proc-eng.h @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2018 eBay Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INC_PROC_ENG_H +#define INC_PROC_ENG_H 1 + +/* The Incremental Processing Engine is a framework for incrementally + * processing changes from different inputs. The main user is ovn-controller. + * To compute desired states (e.g. openflow rules) based on many inputs (e.g. + * south-bound DB tables, local OVSDB interfaces, etc.), it is straightforward + * to recompute everything when there is any change in any inputs, but it + * is inefficient when the size of the input data becomes large. Instead, + * tracking the changes and update the desired states based on what's changed + * is more efficient and scalable. However, it is not straightforward to + * implement the change-based processing when there are a big number of + * inputs. In addition, what makes it more complicated is that intermediate + * results needs to be computed, which needs to be reused in different part + * of the processing and finally generates the final desired states. It is + * proved to be difficult and error-prone to implement this kind of complex + * processing by ad-hoc implementation. + * + * This framework is to provide a generic way to solve the above problem. + * It does not understand the processing logic, but provides a unified way + * to describe the inputs and dependencies clearly, with interfaces for + * users to implement the processing logic for how to handle each input + * changes. + * + * The engine is composed of engine_nodes. Each engine_node is either + * an input, an output or both (intermediate result). Each engine node + * maintains its own data, which is persistent across interactions. Each node + * has zero to ENGINE_MAX_INPUT inputs, which creates a DAG (directed + * acyclic graph). For each input of each engine_node, there is a + * change_handler to process changes of that input, and update the data + * of the engine_node. Then the user can simply call the run() method + * of the engine so that the processing will happen in the order according + * to the dependencies defined and handle the changes incrementally. + * + * While the more fine-grained dependencies and change-handlers are + * implemented, the more efficient the processing will be, it is not + * realistic to implement all change-processing for all inputs (and + * intermediate results). The engine doesn't require change-handler to be + * implemented for every input of every node. Users can choose to implement + * the most important change-handlers (for the changes happens most + * frequently) for overall performance. When there is no change_handler + * defined for a certain input on a certain engine_node, the run() method + * of the engine_node will be called to fall-back to a full recompute + * against all its inputs. + */ + +#define ENGINE_MAX_INPUT 256 +#define ENGINE_MAX_OVSDB_INDEX 256 + +struct engine_context { + struct ovsdb_idl_txn *ovs_idl_txn; + struct ovsdb_idl_txn *ovnsb_idl_txn; +}; + +struct engine_node; + +struct engine_node_input { + /* The input node. */ + struct engine_node *node; + + /* Change handler for changes of the input node. The changes may need to be + * evaluated against all the other inputs. Returns: + * - true: if change can be handled + * - false: if change cannot be handled (indicating full recompute needed) + */ + bool (*change_handler)(struct engine_node *node); +}; + +struct engine_node { + /* A unique id to distinguish each iteration of the engine_run(). */ + uint64_t run_id; + + /* A unique name for each node. */ + char *name; + + /* Number of inputs of this node. */ + size_t n_inputs; + + /* Inputs of this node. */ + struct engine_node_input inputs[ENGINE_MAX_INPUT]; + + /* Data of this node. It is vague and interpreted by the related functions. + * The content of the data should be changed only by the change_handlers + * and run() function of the current node. Users should ensure that the + * data is read-only in change-handlers of the nodes that depends on this + * node. */ + void *data; + + /* Whether the data changed in the last engine run. */ + bool changed; + + /* Method to initialize data. It may be NULL. */ + void (*init)(struct engine_node *); + + /* Method to clean up data. It may be NULL. */ + void (*cleanup)(struct engine_node *); + + /* Fully processes all inputs of this node and regenerates the data + * of this node */ + void (*run)(struct engine_node *); +}; + +/* Initialize the data for the engine nodes recursively. It calls each node's + * init() method if not NULL. It should be called before the main loop. */ +void engine_init(struct engine_node *); + +/* Execute the processing recursively, which should be called in the main + * loop. */ +void engine_run(struct engine_node *, uint64_t run_id); + +/* Clean up the data for the engine nodes recursively. It calls each node's + * cleanup() method if not NULL. It should be called before the program + * terminates. */ +void engine_cleanup(struct engine_node *); + +/* Check if engine needs to run, i.e. any change to be processed. */ +bool +engine_need_run(struct engine_node *); + +/* Get the input node with for */ +struct engine_node * engine_get_input(const char *input_name, + struct engine_node *); + +/* Add an input (dependency) for , with corresponding change_handler, + * which can be NULL. If the change_handler is NULL, the engine will not + * be able to process the change incrementally, and will fall back to call + * the run method to recompute. */ +void engine_add_input(struct engine_node *node, struct engine_node *input, + bool (*change_handler)(struct engine_node *)); + +/* Force the engine to recompute everything if set to true. It is used + * in circumstances when we are not sure there is change or not, or + * when there is change but the engine couldn't be executed in that + * iteration, and the change can't be tracked across iterations */ +void engine_set_force_recompute(bool val); + +const struct engine_context * engine_get_context(void); + +void engine_set_context(const struct engine_context *); + +struct ed_ovsdb_index { + const char *name; + struct ovsdb_idl_index *index; +}; + +struct ed_type_ovsdb_table { + const void *table; + size_t n_indexes; + struct ed_ovsdb_index indexes[ENGINE_MAX_OVSDB_INDEX]; +}; + +#define EN_OVSDB_GET(NODE) \ + (((struct ed_type_ovsdb_table *)NODE->data)->table) + +struct ovsdb_idl_index * engine_ovsdb_node_get_index(struct engine_node *, + const char *name); + +void engine_ovsdb_node_add_index(struct engine_node *, const char *name, + struct ovsdb_idl_index *); + +/* Macro to define an engine node. */ +#define ENGINE_NODE(NAME, NAME_STR) \ + struct engine_node en_##NAME = { \ + .name = NAME_STR, \ + .data = &ed_##NAME, \ + .init = en_##NAME##_init, \ + .run = en_##NAME##_run, \ + .cleanup = en_##NAME##_cleanup, \ + }; + +/* Macro to define member functions of an engine node which represents + * a table of OVSDB */ +#define ENGINE_FUNC_OVSDB(DB_NAME, TBL_NAME) \ +static void \ +en_##DB_NAME##_##TBL_NAME##_run(struct engine_node *node) \ +{ \ + static bool first_run = true; \ + if (first_run) { \ + first_run = false; \ + node->changed = true; \ + return; \ + } \ + const struct DB_NAME##rec_##TBL_NAME##_table *table = \ + EN_OVSDB_GET(node); \ + if (DB_NAME##rec_##TBL_NAME##_table_track_get_first(table)) { \ + node->changed = true; \ + return; \ + } \ + node->changed = false; \ +} \ +static void (*en_##DB_NAME##_##TBL_NAME##_init)(struct engine_node *node) \ + = NULL; \ +static void (*en_##DB_NAME##_##TBL_NAME##_cleanup)(struct engine_node *node) \ + = NULL; + +/* Macro to define member functions of an engine node which represents + * a table of OVN SB DB */ +#define ENGINE_FUNC_SB(TBL_NAME) \ + ENGINE_FUNC_OVSDB(sb, TBL_NAME) + +/* Macro to define member functions of an engine node which represents + * a table of open_vswitch DB */ +#define ENGINE_FUNC_OVS(TBL_NAME) \ + ENGINE_FUNC_OVSDB(ovs, TBL_NAME) + +/* Macro to define an engine node which represents a table of OVSDB */ +#define ENGINE_NODE_OVSDB(DB_NAME, DB_NAME_STR, TBL_NAME, TBL_NAME_STR, IDL) \ + struct ed_type_ovsdb_table ed_##DB_NAME##_##TBL_NAME; \ + memset(&ed_##DB_NAME##_##TBL_NAME, 0, sizeof ed_##DB_NAME##_##TBL_NAME); \ + ovs_assert(IDL); \ + ed_##DB_NAME##_##TBL_NAME.table = \ + DB_NAME##rec_##TBL_NAME##_table_get(IDL); \ + ENGINE_NODE(DB_NAME##_##TBL_NAME, DB_NAME_STR"_"TBL_NAME_STR) + +/* Macro to define an engine node which represents a table of OVN SB DB */ +#define ENGINE_NODE_SB(TBL_NAME, TBL_NAME_STR) \ + ENGINE_NODE_OVSDB(sb, "SB", TBL_NAME, TBL_NAME_STR, ovnsb_idl_loop.idl); + +/* Macro to define an engine node which represents a table of open_vswitch + * DB */ +#define ENGINE_NODE_OVS(TBL_NAME, TBL_NAME_STR) \ + ENGINE_NODE_OVSDB(ovs, "OVS", TBL_NAME, TBL_NAME_STR, ovs_idl_loop.idl); + +#endif /* ovn/lib/inc-proc-eng.h */ From patchwork Mon Aug 13 17:48:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 957077 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="uU/T62fQ"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41q3FR4hlsz9sBD for ; Tue, 14 Aug 2018 03:51:39 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id D931BDB7; Mon, 13 Aug 2018 17:48:37 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id E6611D3A for ; Mon, 13 Aug 2018 17:48:34 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f67.google.com (mail-pl0-f67.google.com [209.85.160.67]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 5FB79765 for ; Mon, 13 Aug 2018 17:48:34 +0000 (UTC) Received: by mail-pl0-f67.google.com with SMTP id w19-v6so7193877ply.8 for ; Mon, 13 Aug 2018 10:48:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xWCSyqqo/S3uBw++xnK0s6RKtNtBbYOL0Nl4zgJuSrQ=; b=uU/T62fQ9XEX45oqEhzOstQqHR/zEgL6M/IIjDiHFK5pCTiPY+ACku64zmEBBArGqj ipxXrjh4L9VE+NY5MM28GH/mPuLH7TXBfSmZu2avElG3Fh1FspwlqmggKHQ/FaQwUjMX 8WQ3TDtgTxnV/T2sluJrqSIKL21xoldbLpQ748+Ef4xVN8KLRi8ratHb4rAAGu9dy8yZ tkz3De+QJaK/h8ZRKx97A1GzQRWaA1lFnEQ315qj+UhXbajqPB6svi9gDeVD748WTv+H bz3L67aJT2ZLIo4G7i/tCH09KYidT2VxG0IBCdbLQ1Ol2nP5Q8bfQn+0nRA7D18wjcAt 1NYQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=xWCSyqqo/S3uBw++xnK0s6RKtNtBbYOL0Nl4zgJuSrQ=; b=EMsZyEZ2QZ8CmkvLnXyqKK3A2N0mcdblYCa9FwhLOS2FXzpt4iSEz8vMQfdQKX1uRu DKTve3HuTZZjuWIhxQTh3GhqKwF8nfTgbJARiDjkRTeqjpPFj8HJIN/Ft2UUuoIOqHyV r1amMiqLtZwlV+5VXFn992cE6rGBhhR9b7W7t1elZRNG324AEDSLWZZW3581SiFOuSvC VqhqfSzgWFF2Jd/2GzP6ujk40Pu4w1mIWUIQcCd6FilvZBoSyMvFdOG6NtqaotLFER/K Xm1HXiRZXzAIupF5aYKmld86zKwlSAtcS5EXSlzLHn/SVIycRjzSgUeSXPP+AEhC7k0g ai9g== X-Gm-Message-State: AOUpUlFDC+OTqnw2i1M9SF8P80AYowh2Hog0KJfyLqoOM3TVuYbAuJys XYKr6mu4ktt02keoU86M4rPwQzGu X-Google-Smtp-Source: AA+uWPw14vpBI9vxU8oxptRkdJn9lQrESjeRsqpx97fP+H0izwTqN5QPsS7sln8ieoaIiYxdeFBGwg== X-Received: by 2002:a17:902:bc49:: with SMTP id t9-v6mr17402690plz.116.1534182513685; Mon, 13 Aug 2018 10:48:33 -0700 (PDT) Received: from localhost.localdomain.localdomain ([216.113.160.70]) by smtp.gmail.com with ESMTPSA id d22-v6sm38068664pfk.69.2018.08.13.10.48.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Aug 2018 10:48:33 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Mon, 13 Aug 2018 10:48:05 -0700 Message-Id: <1534182499-75914-7-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> References: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v5 06/20] ovn-controller: Track OVSDB changes X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org Track OVSDB changes for future patches of incremental processing Signed-off-by: Han Zhou --- ovn/controller/bfd.c | 4 ++-- ovn/controller/binding.c | 16 ++++++++-------- ovn/controller/encaps.c | 12 ++++++------ ovn/controller/ovn-controller.c | 22 +++++++++++++--------- ovn/controller/physical.c | 12 ++++++------ 5 files changed, 35 insertions(+), 31 deletions(-) diff --git a/ovn/controller/bfd.c b/ovn/controller/bfd.c index 051781f..6fca7e0 100644 --- a/ovn/controller/bfd.c +++ b/ovn/controller/bfd.c @@ -34,8 +34,8 @@ bfd_register_ovs_idl(struct ovsdb_idl *ovs_idl) { /* NOTE: this assumes that binding.c has added the * ovsrec_interface table */ - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_bfd); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_bfd_status); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_bfd); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_bfd_status); } diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c index 021ecdd..8d5f13d 100644 --- a/ovn/controller/binding.c +++ b/ovn/controller/binding.c @@ -53,16 +53,16 @@ binding_register_ovs_idl(struct ovsdb_idl *ovs_idl) ovsdb_idl_add_column(ovs_idl, &ovsrec_bridge_col_ports); ovsdb_idl_add_table(ovs_idl, &ovsrec_table_port); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_name); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_interfaces); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_qos); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_name); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_interfaces); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_qos); ovsdb_idl_add_table(ovs_idl, &ovsrec_table_interface); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_name); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_external_ids); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_bfd); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_bfd_status); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_status); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_name); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_external_ids); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_bfd); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_bfd_status); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_status); ovsdb_idl_add_table(ovs_idl, &ovsrec_table_qos); ovsdb_idl_add_column(ovs_idl, &ovsrec_qos_col_type); diff --git a/ovn/controller/encaps.c b/ovn/controller/encaps.c index fde0175..49ce8af 100644 --- a/ovn/controller/encaps.c +++ b/ovn/controller/encaps.c @@ -32,13 +32,13 @@ encaps_register_ovs_idl(struct ovsdb_idl *ovs_idl) ovsdb_idl_add_table(ovs_idl, &ovsrec_table_bridge); ovsdb_idl_add_column(ovs_idl, &ovsrec_bridge_col_ports); ovsdb_idl_add_table(ovs_idl, &ovsrec_table_port); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_name); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_interfaces); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_external_ids); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_name); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_interfaces); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_external_ids); ovsdb_idl_add_table(ovs_idl, &ovsrec_table_interface); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_name); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_type); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_options); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_name); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_type); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_options); } /* Enough context to create a new tunnel, using tunnel_add(). */ diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 85921a0..4dc9681 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -516,16 +516,16 @@ ctrl_register_ovs_idl(struct ovsdb_idl *ovs_idl) ovsdb_idl_add_column(ovs_idl, &ovsrec_open_vswitch_col_external_ids); ovsdb_idl_add_column(ovs_idl, &ovsrec_open_vswitch_col_bridges); ovsdb_idl_add_table(ovs_idl, &ovsrec_table_interface); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_name); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_bfd); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_bfd_status); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_type); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_options); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_ofport); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_name); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_bfd); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_bfd_status); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_type); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_options); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_ofport); ovsdb_idl_add_table(ovs_idl, &ovsrec_table_port); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_name); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_interfaces); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_external_ids); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_name); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_interfaces); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_external_ids); ovsdb_idl_add_table(ovs_idl, &ovsrec_table_bridge); ovsdb_idl_add_column(ovs_idl, &ovsrec_bridge_col_ports); ovsdb_idl_add_column(ovs_idl, &ovsrec_bridge_col_name); @@ -630,6 +630,7 @@ main(int argc, char *argv[]) &sbrec_mac_binding_col_logical_port, &sbrec_mac_binding_col_ip); + ovsdb_idl_track_add_all(ovnsb_idl_loop.idl); ovsdb_idl_omit_alert(ovnsb_idl_loop.idl, &sbrec_chassis_col_nb_cfg); update_sb_monitors(ovnsb_idl_loop.idl, NULL, NULL, NULL); ovsdb_idl_get_initial_snapshot(ovnsb_idl_loop.idl); @@ -866,6 +867,9 @@ main(int argc, char *argv[]) } } } + + ovsdb_idl_track_clear(ovnsb_idl_loop.idl); + ovsdb_idl_track_clear(ovs_idl_loop.idl); poll_block(); if (should_service_stop()) { exiting = true; diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c index c38d7b0..a5e0ddf 100644 --- a/ovn/controller/physical.c +++ b/ovn/controller/physical.c @@ -51,14 +51,14 @@ physical_register_ovs_idl(struct ovsdb_idl *ovs_idl) ovsdb_idl_add_column(ovs_idl, &ovsrec_bridge_col_ports); ovsdb_idl_add_table(ovs_idl, &ovsrec_table_port); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_name); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_interfaces); - ovsdb_idl_add_column(ovs_idl, &ovsrec_port_col_external_ids); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_name); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_interfaces); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_port_col_external_ids); ovsdb_idl_add_table(ovs_idl, &ovsrec_table_interface); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_name); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_ofport); - ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_external_ids); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_name); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_ofport); + ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_external_ids); } static struct simap localvif_to_ofport = From patchwork Mon Aug 13 17:48:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 957084 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="NlY0Avk5"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41q3K13N7Pz9sBD for ; Tue, 14 Aug 2018 03:54:45 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id A0DADE3D; Mon, 13 Aug 2018 17:48:44 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 7C749DA3 for ; Mon, 13 Aug 2018 17:48:40 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f196.google.com (mail-pg1-f196.google.com [209.85.215.196]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 2195F788 for ; Mon, 13 Aug 2018 17:48:36 +0000 (UTC) Received: by mail-pg1-f196.google.com with SMTP id a11-v6so7851734pgw.6 for ; Mon, 13 Aug 2018 10:48:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=coDYLkH2ksueUvEAsFpIWEp09n4NKmWORxtxS1KjnCo=; b=NlY0Avk5Lz6je/I3j0SJkrZ6VbF706L+01JBVTURpH0kUSI33B24Z6SklfuZI2h68+ X4ozLqH8V7GpUH603E8cSiPavG5f82GlaUfWQH5kzVQYYgOsYe0o5sE/C9LMY+mzClnc jriOVsjBImASJerARMCHF+wZe9y4AZ0OmjFBxode11uCU4E/nOdaOIuTjPwx2b7CXHqP KhYz2rpSkjoa5eoWZ1bn8Ss93f51+/ZXyX2ihgnEn5IXE2t+rRyNHiTqq4+8ENKZlOUN doAVC7xD+SiHWoMZcLVw0xaz0feu/TaWQWyUFv7wnmAh3HyaqAMKkpm0VbNph6chWTNw 7sfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=coDYLkH2ksueUvEAsFpIWEp09n4NKmWORxtxS1KjnCo=; b=BI1CuvAsEui2AqjvPGBfVv9DfqZmDjBSGiEWtYYRNJEaXABJTok/kdG7yUdJnvel4J aLwhhz5A5x6/Bs/N8XLxbjE0umr3LzyXvjWfa3fNTOU0DZHiEJQPF3++HzfztGKDC/og bz+5tjfp1yYAF5pCx90p33s9/ueMIjEK1H7A60zBv/skd7eN9zO6o3NE6QK1CsnhpoKs GfhvYQXnccIW+nQN4oJZ9WPHhYl29WiXx7NxBkN1pmPaOqg+x33NHAdryiXCiUShNGJ0 0OBEBKzG4R442qr+Nw+ziIcMEdhqp71MTKIkanjLyNEZdibHznZwjG7c4abmyP4sTUzE +dnw== X-Gm-Message-State: AOUpUlEFGzNpAKcdYxzCdlmMjb7lycBHnMFo8tdW2kwUULo2AtUvXQ7Z X/hxOGyBYrVOW9q9H3e1iEgSt5R/ X-Google-Smtp-Source: AA+uWPxqzNc0+uclHGasj8FatSa+jVDlwCB3t1FtKzkpRFRW1LMR+vySMNHtIKztekm6TX5d5sZ3Aw== X-Received: by 2002:a62:fccd:: with SMTP id e196-v6mr19915371pfh.245.1534182514561; Mon, 13 Aug 2018 10:48:34 -0700 (PDT) Received: from localhost.localdomain.localdomain ([216.113.160.70]) by smtp.gmail.com with ESMTPSA id d22-v6sm38068664pfk.69.2018.08.13.10.48.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Aug 2018 10:48:33 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Mon, 13 Aug 2018 10:48:06 -0700 Message-Id: <1534182499-75914-8-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> References: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v5 07/20] ovn-controller: Initial use of incremental engine. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org Incremental proccessing engine is used to compute flows. In this patch we create below engine nodes: - Engine nodes for each OVSDB table in local OVS DB and SB DB. - runtime_data: compute and maintain intermediate result such as local_datapath, etc. - mff_ovn_geneve: MFF_* field ID for our Geneve option, which is provided by switch. - flow_output: compute and maintain computed flow table. In this patch the ovn flow table is persistent across main loop iterations, and a new index of SB uuid is maintained for the desired flow table, which will be useful for next patches for incremental processing. In each iteration if there is any input change then everything is still recomputed, but there is no recompute if there is no change. For example, pinctrl input will not trigger flow recompute any more. Signed-off-by: Han Zhou --- include/ovn/actions.h | 3 + ovn/controller/binding.c | 1 + ovn/controller/lflow.c | 96 +++-- ovn/controller/lflow.h | 7 +- ovn/controller/ofctrl.c | 261 +++++++++---- ovn/controller/ofctrl.h | 33 +- ovn/controller/ovn-controller.c | 816 +++++++++++++++++++++++++++++++--------- ovn/controller/physical.c | 71 ++-- ovn/controller/physical.h | 2 +- ovn/lib/actions.c | 9 +- ovn/lib/extend-table.c | 60 ++- ovn/lib/extend-table.h | 16 +- 12 files changed, 1020 insertions(+), 355 deletions(-) diff --git a/include/ovn/actions.h b/include/ovn/actions.h index 1c0c67c..ff770bc 100644 --- a/include/ovn/actions.h +++ b/include/ovn/actions.h @@ -521,6 +521,9 @@ struct ovnact_encode_params { /* A struct to figure out the meter_id for meter actions. */ struct ovn_extend_table *meter_table; + /* The logical flow uuid that drove this action. */ + struct uuid lflow_uuid; + /* OVN maps each logical flow table (ltable), one-to-one, onto a physical * OpenFlow flow table (ptable). A number of parameters describe this * mapping and data related to flow tables: diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c index 8d5f13d..a4b30cb 100644 --- a/ovn/controller/binding.c +++ b/ovn/controller/binding.c @@ -481,6 +481,7 @@ consider_local_datapath(struct ovsdb_idl_txn *ovnsb_idl_txn, update_local_lport_ids(local_lport_ids, binding_rec); } + ovs_assert(ovnsb_idl_txn); if (ovnsb_idl_txn) { const char *vif_chassis = smap_get(&binding_rec->options, "requested-chassis"); diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c index 8db8192..72b1ec7 100644 --- a/ovn/controller/lflow.c +++ b/ovn/controller/lflow.c @@ -62,7 +62,7 @@ struct condition_aux { const struct sset *active_tunnels; }; -static void consider_logical_flow( +static bool consider_logical_flow( struct ovsdb_idl_index *sbrec_chassis_by_name, struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath, struct ovsdb_idl_index *sbrec_port_binding_by_name, @@ -76,10 +76,10 @@ static void consider_logical_flow( const struct shash *port_groups, const struct sset *active_tunnels, const struct sset *local_lport_ids, - uint32_t *conj_id_ofs, - struct hmap *flow_table, + struct ovn_desired_flow_table *, struct ovn_extend_table *group_table, - struct ovn_extend_table *meter_table); + struct ovn_extend_table *meter_table, + uint32_t *conj_id_ofs); static bool lookup_port_cb(const void *aux_, const char *port_name, unsigned int *portp) @@ -153,11 +153,11 @@ add_logical_flows( const struct shash *port_groups, const struct sset *active_tunnels, const struct sset *local_lport_ids, - struct hmap *flow_table, + struct ovn_desired_flow_table *flow_table, struct ovn_extend_table *group_table, - struct ovn_extend_table *meter_table) + struct ovn_extend_table *meter_table, + uint32_t *conj_id_ofs) { - uint32_t conj_id_ofs = 1; const struct sbrec_logical_flow *lflow; struct hmap dhcp_opts = HMAP_INITIALIZER(&dhcp_opts); @@ -180,14 +180,19 @@ add_logical_flows( nd_ra_opts_init(&nd_ra_opts); SBREC_LOGICAL_FLOW_TABLE_FOR_EACH (lflow, logical_flow_table) { - consider_logical_flow(sbrec_chassis_by_name, - sbrec_multicast_group_by_name_datapath, - sbrec_port_binding_by_name, - lflow, local_datapaths, - chassis, &dhcp_opts, &dhcpv6_opts, &nd_ra_opts, - addr_sets, port_groups, active_tunnels, - local_lport_ids, &conj_id_ofs, - flow_table, group_table, meter_table); + if (!consider_logical_flow(sbrec_chassis_by_name, + sbrec_multicast_group_by_name_datapath, + sbrec_port_binding_by_name, + lflow, local_datapaths, + chassis, &dhcp_opts, &dhcpv6_opts, + &nd_ra_opts, addr_sets, port_groups, + active_tunnels, local_lport_ids, + flow_table, group_table, meter_table, + conj_id_ofs)) { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5); + VLOG_ERR_RL(&rl, "Conjunction id overflow when processing lflow " + UUID_FMT, UUID_ARGS(&lflow->header_.uuid)); + } } dhcp_opts_destroy(&dhcp_opts); @@ -195,7 +200,18 @@ add_logical_flows( nd_ra_opts_destroy(&nd_ra_opts); } -static void +static bool +update_conj_id_ofs(uint32_t *conj_id_ofs, uint32_t n_conjs) +{ + if (*conj_id_ofs + n_conjs < *conj_id_ofs) { + /* overflow */ + return false; + } + *conj_id_ofs += n_conjs; + return true; +} + +static bool consider_logical_flow( struct ovsdb_idl_index *sbrec_chassis_by_name, struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath, @@ -210,20 +226,24 @@ consider_logical_flow( const struct shash *port_groups, const struct sset *active_tunnels, const struct sset *local_lport_ids, - uint32_t *conj_id_ofs, - struct hmap *flow_table, + struct ovn_desired_flow_table *flow_table, struct ovn_extend_table *group_table, - struct ovn_extend_table *meter_table) + struct ovn_extend_table *meter_table, + uint32_t *conj_id_ofs) { /* 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) { - return; + VLOG_DBG("lflow "UUID_FMT" has no datapath binding, skip", + UUID_ARGS(&lflow->header_.uuid)); + return true; } if (!get_local_datapath(local_datapaths, ldp->tunnel_key)) { - return; + VLOG_DBG("lflow "UUID_FMT" is not for local datapath, skip", + UUID_ARGS(&lflow->header_.uuid)); + return true; } /* Determine translation of logical table IDs to physical table IDs. */ @@ -261,7 +281,7 @@ consider_logical_flow( free(error); ovnacts_free(ovnacts.data, ovnacts.size); ofpbuf_uninit(&ovnacts); - return; + return true; } /* Translate OVN match into table of OpenFlow matches. */ @@ -285,7 +305,7 @@ consider_logical_flow( free(error); ovnacts_free(ovnacts.data, ovnacts.size); ofpbuf_uninit(&ovnacts); - return; + return true; } struct lookup_port_aux aux = { @@ -307,10 +327,12 @@ consider_logical_flow( expr_destroy(expr); if (hmap_is_empty(&matches)) { + VLOG_DBG("lflow "UUID_FMT" matches are empty, skip", + UUID_ARGS(&lflow->header_.uuid)); ovnacts_free(ovnacts.data, ovnacts.size); ofpbuf_uninit(&ovnacts); expr_matches_destroy(&matches); - return; + return true; } /* Encode OVN logical actions into OpenFlow. */ @@ -322,6 +344,7 @@ consider_logical_flow( .is_switch = is_switch(ldp), .group_table = group_table, .meter_table = meter_table, + .lflow_uuid = lflow->header_.uuid, .pipeline = ingress ? OVNACT_P_INGRESS : OVNACT_P_EGRESS, .ingress_ptable = OFTABLE_LOG_INGRESS_PIPELINE, @@ -350,13 +373,18 @@ consider_logical_flow( char buf[16]; snprintf(buf, sizeof(buf), "%"PRId64"_%"PRId64, dp_id, port_id); if (!sset_contains(local_lport_ids, buf)) { + VLOG_DBG("lflow "UUID_FMT + " port %s in match is not local, skip", + UUID_ARGS(&lflow->header_.uuid), + buf); continue; } } } if (!m->n) { ofctrl_add_flow(flow_table, ptable, lflow->priority, - lflow->header_.uuid.parts[0], &m->match, &ofpacts); + lflow->header_.uuid.parts[0], &m->match, &ofpacts, + &lflow->header_.uuid); } else { uint64_t conj_stubs[64 / 8]; struct ofpbuf conj; @@ -372,7 +400,7 @@ consider_logical_flow( dst->n_clauses = src->n_clauses; } ofctrl_add_flow(flow_table, ptable, lflow->priority, 0, &m->match, - &conj); + &conj, &lflow->header_.uuid); ofpbuf_uninit(&conj); } } @@ -380,7 +408,7 @@ consider_logical_flow( /* Clean up. */ expr_matches_destroy(&matches); ofpbuf_uninit(&ofpacts); - *conj_id_ofs += n_conjs; + return update_conj_id_ofs(conj_id_ofs, n_conjs); } static void @@ -398,7 +426,7 @@ put_load(const uint8_t *data, size_t len, static void consider_neighbor_flow(struct ovsdb_idl_index *sbrec_port_binding_by_name, const struct sbrec_mac_binding *b, - struct hmap *flow_table) + struct ovn_desired_flow_table *flow_table) { const struct sbrec_port_binding *pb = lport_lookup_by_name(sbrec_port_binding_by_name, b->logical_port); @@ -440,7 +468,8 @@ consider_neighbor_flow(struct ovsdb_idl_index *sbrec_port_binding_by_name, uint64_t stub[1024 / 8]; struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(stub); put_load(mac.ea, sizeof mac.ea, MFF_ETH_DST, 0, 48, &ofpacts); - ofctrl_add_flow(flow_table, OFTABLE_MAC_BINDING, 100, 0, &match, &ofpacts); + ofctrl_add_flow(flow_table, OFTABLE_MAC_BINDING, 100, 0, &match, &ofpacts, + &b->header_.uuid); ofpbuf_uninit(&ofpacts); } @@ -449,7 +478,7 @@ consider_neighbor_flow(struct ovsdb_idl_index *sbrec_port_binding_by_name, static void add_neighbor_flows(struct ovsdb_idl_index *sbrec_port_binding_by_name, const struct sbrec_mac_binding_table *mac_binding_table, - struct hmap *flow_table) + struct ovn_desired_flow_table *flow_table) { const struct sbrec_mac_binding *b; SBREC_MAC_BINDING_TABLE_FOR_EACH (b, mac_binding_table) { @@ -473,9 +502,10 @@ lflow_run(struct ovsdb_idl_index *sbrec_chassis_by_name, const struct shash *port_groups, const struct sset *active_tunnels, const struct sset *local_lport_ids, - struct hmap *flow_table, + struct ovn_desired_flow_table *flow_table, struct ovn_extend_table *group_table, - struct ovn_extend_table *meter_table) + struct ovn_extend_table *meter_table, + uint32_t *conj_id_ofs) { COVERAGE_INC(lflow_run); @@ -485,7 +515,7 @@ lflow_run(struct ovsdb_idl_index *sbrec_chassis_by_name, dhcpv6_options_table, logical_flow_table, local_datapaths, chassis, addr_sets, port_groups, active_tunnels, local_lport_ids, flow_table, group_table, - meter_table); + meter_table, conj_id_ofs); add_neighbor_flows(sbrec_port_binding_by_name, mac_binding_table, flow_table); } diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h index d193381..b4120d0 100644 --- a/ovn/controller/lflow.h +++ b/ovn/controller/lflow.h @@ -37,6 +37,7 @@ struct ovn_extend_table; struct ovsdb_idl_index; +struct ovn_desired_flow_table; struct hmap; struct sbrec_chassis; struct sbrec_dhcp_options_table; @@ -78,9 +79,11 @@ void lflow_run(struct ovsdb_idl_index *sbrec_chassis_by_name, const struct shash *port_groups, const struct sset *active_tunnels, const struct sset *local_lport_ids, - struct hmap *flow_table, + struct ovn_desired_flow_table *, struct ovn_extend_table *group_table, - struct ovn_extend_table *meter_table); + struct ovn_extend_table *meter_table, + uint32_t *conj_id_ofs); + void lflow_destroy(void); #endif /* ovn/lflow.h */ diff --git a/ovn/controller/ofctrl.c b/ovn/controller/ofctrl.c index 96c57f1..91d7f90 100644 --- a/ovn/controller/ofctrl.c +++ b/ovn/controller/ofctrl.c @@ -20,6 +20,7 @@ #include "dp-packet.h" #include "flow.h" #include "hash.h" +#include "hindex.h" #include "lflow.h" #include "ofctrl.h" #include "openflow/openflow.h" @@ -52,7 +53,8 @@ VLOG_DEFINE_THIS_MODULE(ofctrl); /* An OpenFlow flow. */ struct ovn_flow { - struct hmap_node hmap_node; /* For match based hashing. */ + struct hmap_node match_hmap_node; /* For match based hashing. */ + struct hindex_node uuid_hindex_node; /* For uuid based hashing. */ struct ovs_list list_node; /* For handling lists of flows. */ /* Key. */ @@ -61,14 +63,16 @@ struct ovn_flow { struct minimatch match; /* Data. */ + struct uuid sb_uuid; struct ofpact *ofpacts; size_t ofpacts_len; uint64_t cookie; }; -static uint32_t ovn_flow_hash(const struct ovn_flow *); +static uint32_t ovn_flow_match_hash(const struct ovn_flow *); static struct ovn_flow *ovn_flow_lookup(struct hmap *flow_table, - const struct ovn_flow *target); + const struct ovn_flow *target, + bool cmp_sb_uuid); static char *ovn_flow_to_string(const struct ovn_flow *); static void ovn_flow_log(const struct ovn_flow *, const char *action); static void ovn_flow_destroy(struct ovn_flow *); @@ -146,6 +150,10 @@ static struct ovn_extend_table *meters; * S_CLEAR_FLOWS or S_UPDATE_FLOWS, this is really the option we have. */ static enum mf_field_id mff_ovn_geneve; +/* Indicates if flows need to be reinstalled for scenarios when ovs + * is restarted, even if there is no change in the desired flow table. */ +static bool need_reinstall_flows; + static ovs_be32 queue_msg(struct ofpbuf *); static struct ofpbuf *encode_flow_mod(struct ofputil_flow_mod *); @@ -154,8 +162,8 @@ static struct ofpbuf *encode_group_mod(const struct ofputil_group_mod *); static struct ofpbuf *encode_meter_mod(const struct ofputil_meter_mod *); -static void ovn_flow_table_clear(struct hmap *flow_table); -static void ovn_flow_table_destroy(struct hmap *flow_table); +static void ovn_installed_flow_table_clear(void); +static void ovn_installed_flow_table_destroy(void); static void ofctrl_recv(const struct ofp_header *, enum ofptype); @@ -375,6 +383,7 @@ run_S_CLEAR_FLOWS(void) { VLOG_DBG("clearing all flows"); + need_reinstall_flows = true; /* Send a flow_mod to delete all flows. */ struct ofputil_flow_mod fm = { .table_id = OFPTT_ALL, @@ -384,9 +393,6 @@ run_S_CLEAR_FLOWS(void) queue_msg(encode_flow_mod(&fm)); minimatch_destroy(&fm.match); - /* Clear installed_flows, to match the state of the switch. */ - ovn_flow_table_clear(&installed_flows); - /* Send a group_mod to delete all groups. */ struct ofputil_group_mod gm; memset(&gm, 0, sizeof gm); @@ -397,6 +403,9 @@ run_S_CLEAR_FLOWS(void) queue_msg(encode_group_mod(&gm)); ofputil_uninit_group_mod(&gm); + /* Clear installed_flows, to match the state of the switch. */ + ovn_installed_flow_table_clear(); + /* Clear existing groups, to match the state of the switch. */ if (groups) { ovn_extend_table_clear(groups, true); @@ -477,11 +486,21 @@ recv_S_UPDATE_FLOWS(const struct ofp_header *oh, enum ofptype type, } } + +enum mf_field_id +ofctrl_get_mf_field_id(void) +{ + if (!rconn_is_connected(swconn)) { + return 0; + } + return (state == S_CLEAR_FLOWS || state == S_UPDATE_FLOWS + ? mff_ovn_geneve : 0); +} + /* Runs the OpenFlow state machine against 'br_int', which is local to the * hypervisor on which we are running. Attempts to negotiate a Geneve option - * field for class OVN_GENEVE_CLASS, type OVN_GENEVE_TYPE. If successful, - * returns the MFF_* field ID for the option, otherwise returns 0. */ -enum mf_field_id + * field for class OVN_GENEVE_CLASS, type OVN_GENEVE_TYPE. */ +void ofctrl_run(const struct ovsrec_bridge *br_int, struct shash *pending_ct_zones) { char *target = xasprintf("unix:%s/%s.mgmt", ovs_rundir(), br_int->name); @@ -494,7 +513,7 @@ ofctrl_run(const struct ovsrec_bridge *br_int, struct shash *pending_ct_zones) rconn_run(swconn); if (!rconn_is_connected(swconn)) { - return 0; + return; } if (seqno != rconn_get_connection_seqno(swconn)) { seqno = rconn_get_connection_seqno(swconn); @@ -557,9 +576,6 @@ ofctrl_run(const struct ovsrec_bridge *br_int, struct shash *pending_ct_zones) * point, so ensure that we come back again without waiting. */ poll_immediate_wake(); } - - return (state == S_CLEAR_FLOWS || state == S_UPDATE_FLOWS - ? mff_ovn_geneve : 0); } void @@ -573,7 +589,7 @@ void ofctrl_destroy(void) { rconn_destroy(swconn); - ovn_flow_table_destroy(&installed_flows); + ovn_installed_flow_table_destroy(); rconn_packet_counter_destroy(tx_counter); expr_symtab_destroy(&symtab); shash_destroy(&symtab); @@ -625,14 +641,17 @@ ofctrl_recv(const struct ofp_header *oh, enum ofptype type) * the OpenFlow table numbered 'table_id' with the given 'priority' and * OpenFlow 'cookie'. The caller retains ownership of 'match' and 'actions'. * + * The flow is also added to a hash index based on sb_uuid. + * * This just assembles the desired flow table in memory. Nothing is actually * sent to the switch until a later call to ofctrl_put(). * * The caller should initialize its own hmap to hold the flows. */ void -ofctrl_add_flow(struct hmap *desired_flows, +ofctrl_add_flow(struct ovn_desired_flow_table *flow_table, uint8_t table_id, uint16_t priority, uint64_t cookie, - const struct match *match, const struct ofpbuf *actions) + const struct match *match, const struct ofpbuf *actions, + const struct uuid *sb_uuid) { struct ovn_flow *f = xmalloc(sizeof *f); f->table_id = table_id; @@ -640,10 +659,14 @@ ofctrl_add_flow(struct hmap *desired_flows, minimatch_init(&f->match, match); f->ofpacts = xmemdup(actions->data, actions->size); f->ofpacts_len = actions->size; - f->hmap_node.hash = ovn_flow_hash(f); + f->sb_uuid = *sb_uuid; + f->match_hmap_node.hash = ovn_flow_match_hash(f); + f->uuid_hindex_node.hash = uuid_hash(&f->sb_uuid); f->cookie = cookie; - if (ovn_flow_lookup(desired_flows, f)) { + ovn_flow_log(f, "ofctrl_add_flow"); + + if (ovn_flow_lookup(&flow_table->match_flow_table, f, true)) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5); if (!VLOG_DROP_DBG(&rl)) { char *s = ovn_flow_to_string(f); @@ -655,19 +678,44 @@ ofctrl_add_flow(struct hmap *desired_flows, return; } - hmap_insert(desired_flows, &f->hmap_node, f->hmap_node.hash); + hmap_insert(&flow_table->match_flow_table, &f->match_hmap_node, + f->match_hmap_node.hash); + hindex_insert(&flow_table->uuid_flow_table, &f->uuid_hindex_node, + f->uuid_hindex_node.hash); +} + +/* Removes a bundles of flows from the flow table. */ +void +ofctrl_remove_flows(struct ovn_desired_flow_table *flow_table, + const struct uuid *sb_uuid) +{ + struct ovn_flow *f, *next; + HINDEX_FOR_EACH_WITH_HASH_SAFE (f, next, uuid_hindex_node, + uuid_hash(sb_uuid), + &flow_table->uuid_flow_table) { + if (uuid_equals(&f->sb_uuid, sb_uuid)) { + ovn_flow_log(f, "ofctrl_remove_flow"); + hmap_remove(&flow_table->match_flow_table, + &f->match_hmap_node); + hindex_remove(&flow_table->uuid_flow_table, &f->uuid_hindex_node); + ovn_flow_destroy(f); + } + } + + /* remove any related group and meter info */ + ovn_extend_table_remove_desired(groups, sb_uuid); + ovn_extend_table_remove_desired(meters, sb_uuid); } /* ovn_flow. */ -/* Returns a hash of the key in 'f'. */ +/* Returns a hash of the match key in 'f'. */ static uint32_t -ovn_flow_hash(const struct ovn_flow *f) +ovn_flow_match_hash(const struct ovn_flow *f) { return hash_2words((f->table_id << 16) | f->priority, minimatch_hash(&f->match, 0)); - } /* Duplicate an ovn_flow structure. */ @@ -680,23 +728,28 @@ ofctrl_dup_flow(struct ovn_flow *src) minimatch_clone(&dst->match, &src->match); dst->ofpacts = xmemdup(src->ofpacts, src->ofpacts_len); dst->ofpacts_len = src->ofpacts_len; - dst->hmap_node.hash = ovn_flow_hash(dst); + dst->sb_uuid = src->sb_uuid; + dst->match_hmap_node.hash = ovn_flow_match_hash(dst); + dst->uuid_hindex_node.hash = uuid_hash(&src->sb_uuid); return dst; } /* Finds and returns an ovn_flow in 'flow_table' whose key is identical to * 'target''s key, or NULL if there is none. */ static struct ovn_flow * -ovn_flow_lookup(struct hmap *flow_table, const struct ovn_flow *target) +ovn_flow_lookup(struct hmap *flow_table, const struct ovn_flow *target, + bool cmp_sb_uuid) { struct ovn_flow *f; - HMAP_FOR_EACH_WITH_HASH (f, hmap_node, target->hmap_node.hash, + HMAP_FOR_EACH_WITH_HASH (f, match_hmap_node, target->match_hmap_node.hash, flow_table) { if (f->table_id == target->table_id && f->priority == target->priority && minimatch_equal(&f->match, &target->match)) { - return f; + if (!cmp_sb_uuid || uuid_equals(&target->sb_uuid, &f->sb_uuid)) { + return f; + } } } return NULL; @@ -706,6 +759,7 @@ static char * ovn_flow_to_string(const struct ovn_flow *f) { struct ds s = DS_EMPTY_INITIALIZER; + ds_put_format(&s, "sb_uuid="UUID_FMT", ", UUID_ARGS(&f->sb_uuid)); ds_put_format(&s, "table_id=%"PRIu8", ", f->table_id); ds_put_format(&s, "priority=%"PRIu16", ", f->priority); minimatch_format(&f->match, NULL, NULL, &s, OFP_DEFAULT_PRIORITY); @@ -736,22 +790,48 @@ ovn_flow_destroy(struct ovn_flow *f) } /* Flow tables of struct ovn_flow. */ +void +ovn_desired_flow_table_init(struct ovn_desired_flow_table *flow_table) +{ + hmap_init(&flow_table->match_flow_table); + hindex_init(&flow_table->uuid_flow_table); +} + +void +ovn_desired_flow_table_clear(struct ovn_desired_flow_table *flow_table) +{ + struct ovn_flow *f, *next; + HMAP_FOR_EACH_SAFE (f, next, match_hmap_node, + &flow_table->match_flow_table) { + hmap_remove(&flow_table->match_flow_table, &f->match_hmap_node); + hindex_remove(&flow_table->uuid_flow_table, &f->uuid_hindex_node); + ovn_flow_destroy(f); + } +} + +void +ovn_desired_flow_table_destroy(struct ovn_desired_flow_table *flow_table) +{ + ovn_desired_flow_table_clear(flow_table); + hmap_destroy(&flow_table->match_flow_table); + hindex_destroy(&flow_table->uuid_flow_table); +} static void -ovn_flow_table_clear(struct hmap *flow_table) +ovn_installed_flow_table_clear(void) { struct ovn_flow *f, *next; - HMAP_FOR_EACH_SAFE (f, next, hmap_node, flow_table) { - hmap_remove(flow_table, &f->hmap_node); + HMAP_FOR_EACH_SAFE (f, next, match_hmap_node, &installed_flows) { + hmap_remove(&installed_flows, &f->match_hmap_node); ovn_flow_destroy(f); } } static void -ovn_flow_table_destroy(struct hmap *flow_table) +ovn_installed_flow_table_destroy(void) { - ovn_flow_table_clear(flow_table); - hmap_destroy(flow_table); + ovn_installed_flow_table_clear(); + hmap_destroy(&installed_flows); } /* Flow table update. */ @@ -891,7 +971,7 @@ add_meter(struct ovn_extend_table_info *m_desired, * in the correct state and not backlogged with existing flow_mods. (Our * criteria for being backlogged appear very conservative, but the socket * between ovn-controller and OVS provides some buffering.) */ -bool +static bool ofctrl_can_put(void) { if (state != S_UPDATE_FLOWS @@ -906,9 +986,7 @@ ofctrl_can_put(void) * with ofctrl_add_flow(). * * Replaces the group table and meter table on the switch, if possible, - * by the contents of '->desired'. Regardless of whether the table is - * updated, this deletes all the groups or meters from the '->desired' - * and frees them. (The hmap itself isn't destroyed.) + * by the contents of '->desired'. * * Sends conntrack flush messages to each zone in 'pending_ct_zones' that * is in the CT_ZONE_OF_QUEUED state and then moves the zone into the @@ -916,16 +994,43 @@ ofctrl_can_put(void) * * This should be called after ofctrl_run() within the main loop. */ void -ofctrl_put(struct hmap *flow_table, struct shash *pending_ct_zones, - const struct sbrec_meter_table *meter_table, int64_t nb_cfg) +ofctrl_put(struct ovn_desired_flow_table *flow_table, + struct shash *pending_ct_zones, + const struct sbrec_meter_table *meter_table, + int64_t nb_cfg, + bool flow_changed) { + static bool skipped_last_time = false; + static int64_t old_nb_cfg = 0; + bool need_put = false; + if (flow_changed || skipped_last_time || need_reinstall_flows) { + need_put = true; + } else if (nb_cfg != old_nb_cfg) { + /* nb_cfg changed since last ofctrl_put() call */ + if (cur_cfg == old_nb_cfg) { + /* we were up-to-date already, so just update with the + * new nb_cfg */ + cur_cfg = nb_cfg; + } else { + need_put = true; + } + } + + old_nb_cfg = nb_cfg; + + if (!need_put) { + VLOG_DBG("ofctrl_put not needed"); + return; + } if (!ofctrl_can_put()) { - ovn_flow_table_clear(flow_table); - ovn_extend_table_clear(groups, false); - ovn_extend_table_clear(meters, false); + VLOG_DBG("ofctrl_put can't be performed"); + skipped_last_time = true; return; } + skipped_last_time = false; + need_reinstall_flows = false; + /* OpenFlow messages to send to the switch to bring it up-to-date. */ struct ovs_list msgs = OVS_LIST_INITIALIZER(&msgs); @@ -980,8 +1085,9 @@ ofctrl_put(struct hmap *flow_table, struct shash *pending_ct_zones, * longer desired, delete them; if any of them should have different * actions, update them. */ struct ovn_flow *i, *next; - HMAP_FOR_EACH_SAFE (i, next, hmap_node, &installed_flows) { - struct ovn_flow *d = ovn_flow_lookup(flow_table, i); + HMAP_FOR_EACH_SAFE (i, next, match_hmap_node, &installed_flows) { + struct ovn_flow *d = ovn_flow_lookup(&flow_table->match_flow_table, + i, false); if (!d) { /* Installed flow is no longer desirable. Delete it from the * switch and from installed_flows. */ @@ -994,9 +1100,13 @@ ofctrl_put(struct hmap *flow_table, struct shash *pending_ct_zones, add_flow_mod(&fm, &msgs); ovn_flow_log(i, "removing installed"); - hmap_remove(&installed_flows, &i->hmap_node); + hmap_remove(&installed_flows, &i->match_hmap_node); ovn_flow_destroy(i); } else { + if (!uuid_equals(&i->sb_uuid, &d->sb_uuid)) { + /* Update installed flow's UUID. */ + i->sb_uuid = d->sb_uuid; + } if (!ofpacts_equal(i->ofpacts, i->ofpacts_len, d->ofpacts, d->ofpacts_len)) { /* Update actions in installed flow. */ @@ -1013,38 +1123,37 @@ ofctrl_put(struct hmap *flow_table, struct shash *pending_ct_zones, /* Replace 'i''s actions by 'd''s. */ free(i->ofpacts); - i->ofpacts = d->ofpacts; + i->ofpacts = xmemdup(d->ofpacts, d->ofpacts_len); i->ofpacts_len = d->ofpacts_len; - d->ofpacts = NULL; - d->ofpacts_len = 0; } - hmap_remove(flow_table, &d->hmap_node); - ovn_flow_destroy(d); } } - /* The previous loop removed from 'flow_table' all of the flows that are - * already installed. Thus, any flows remaining in 'flow_table' need to - * be added to the flow table. */ + /* Iterate through the desired flows and add those that aren't found + * in the installed flow table. */ struct ovn_flow *d; - HMAP_FOR_EACH_SAFE (d, next, hmap_node, flow_table) { - /* Send flow_mod to add flow. */ - struct ofputil_flow_mod fm = { - .match = d->match, - .priority = d->priority, - .table_id = d->table_id, - .ofpacts = d->ofpacts, - .ofpacts_len = d->ofpacts_len, - .new_cookie = htonll(d->cookie), - .command = OFPFC_ADD, - }; - add_flow_mod(&fm, &msgs); - ovn_flow_log(d, "adding installed"); + HMAP_FOR_EACH (d, match_hmap_node, &flow_table->match_flow_table) { + i = ovn_flow_lookup(&installed_flows, d, false); + if (!i) { + /* Send flow_mod to add flow. */ + struct ofputil_flow_mod fm = { + .match = d->match, + .priority = d->priority, + .table_id = d->table_id, + .ofpacts = d->ofpacts, + .ofpacts_len = d->ofpacts_len, + .new_cookie = htonll(d->cookie), + .command = OFPFC_ADD, + }; + add_flow_mod(&fm, &msgs); + ovn_flow_log(d, "adding installed"); - /* Move 'd' from 'flow_table' to installed_flows. */ - hmap_remove(flow_table, &d->hmap_node); - hmap_insert(&installed_flows, &d->hmap_node, d->hmap_node.hash); + /* Copy 'd' from 'flow_table' to installed_flows. */ + struct ovn_flow *new_node = ofctrl_dup_flow(d); + hmap_insert(&installed_flows, &new_node->match_hmap_node, + new_node->match_hmap_node.hash); + } } /* Iterate through the installed groups from previous runs. If they @@ -1069,11 +1178,11 @@ ofctrl_put(struct hmap *flow_table, struct shash *pending_ct_zones, } free(group_string); ofputil_uninit_group_mod(&gm); - ovn_extend_table_remove(groups, installed); + ovn_extend_table_remove_existing(groups, installed); } - /* Move the contents of groups->desired to groups->existing. */ - ovn_extend_table_move(groups); + /* Sync the contents of groups->desired to groups->existing. */ + ovn_extend_table_sync(groups); /* Iterate through the installed meters from previous runs. If they * are not needed delete them. */ @@ -1086,11 +1195,11 @@ ofctrl_put(struct hmap *flow_table, struct shash *pending_ct_zones, }; add_meter_mod(&mm, &msgs); - ovn_extend_table_remove(meters, m_installed); + ovn_extend_table_remove_existing(meters, m_installed); } - /* Move the contents of meters->desired to meters->existing. */ - ovn_extend_table_move(meters); + /* Sync the contents of meters->desired to meters->existing. */ + ovn_extend_table_sync(meters); if (!ovs_list_is_empty(&msgs)) { /* Add a barrier to the list of messages. */ diff --git a/ovn/controller/ofctrl.h b/ovn/controller/ofctrl.h index e3fc95b..1ccdd60 100644 --- a/ovn/controller/ofctrl.h +++ b/ovn/controller/ofctrl.h @@ -21,6 +21,7 @@ #include "openvswitch/meta-flow.h" #include "ovsdb-idl.h" +#include "hindex.h" struct ovn_extend_table; struct hmap; @@ -30,14 +31,25 @@ struct ovsrec_bridge; struct sbrec_meter_table; struct shash; +struct ovn_desired_flow_table { + /* Hash map flow table using flow match conditions as hash key.*/ + struct hmap match_flow_table; + + /* SB uuid index for the nodes in match_flow_table.*/ + struct hindex uuid_flow_table; +}; + /* Interface for OVN main loop. */ void ofctrl_init(struct ovn_extend_table *group_table, struct ovn_extend_table *meter_table); -enum mf_field_id ofctrl_run(const struct ovsrec_bridge *br_int, - struct shash *pending_ct_zones); -bool ofctrl_can_put(void); -void ofctrl_put(struct hmap *flow_table, struct shash *pending_ct_zones, - const struct sbrec_meter_table *meter_table, int64_t nb_cfg); +void ofctrl_run(const struct ovsrec_bridge *br_int, + struct shash *pending_ct_zones); +enum mf_field_id ofctrl_get_mf_field_id(void); +void ofctrl_put(struct ovn_desired_flow_table *, + struct shash *pending_ct_zones, + const struct sbrec_meter_table *, + int64_t nb_cfg, + bool flow_changed); void ofctrl_wait(void); void ofctrl_destroy(void); int64_t ofctrl_get_cur_cfg(void); @@ -51,8 +63,15 @@ char *ofctrl_inject_pkt(const struct ovsrec_bridge *br_int, const struct shash *port_groups); /* Flow table interfaces to the rest of ovn-controller. */ -void ofctrl_add_flow(struct hmap *desired_flows, uint8_t table_id, +void ofctrl_add_flow(struct ovn_desired_flow_table *, uint8_t table_id, uint16_t priority, uint64_t cookie, - const struct match *, const struct ofpbuf *ofpacts); + const struct match *, const struct ofpbuf *ofpacts, + const struct uuid *); + +void ofctrl_remove_flows(struct ovn_desired_flow_table *, const struct uuid *); + +void ovn_desired_flow_table_init(struct ovn_desired_flow_table *); +void ovn_desired_flow_table_clear(struct ovn_desired_flow_table *); +void ovn_desired_flow_table_destroy(struct ovn_desired_flow_table *); #endif /* ovn/ofctrl.h */ diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 4dc9681..bfe99dd 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -60,6 +60,7 @@ #include "timeval.h" #include "timer.h" #include "stopwatch.h" +#include "ovn/lib/inc-proc-eng.h" VLOG_DEFINE_THIS_MODULE(main); @@ -198,15 +199,27 @@ update_sb_monitors(struct ovsdb_idl *ovnsb_idl, ovsdb_idl_condition_destroy(&dns); } +static const char * +br_int_name(const struct ovsrec_open_vswitch *cfg) +{ + return smap_get_def(&cfg->external_ids, "ovn-bridge", DEFAULT_BRIDGE_NAME); +} + static const struct ovsrec_bridge * create_br_int(struct ovsdb_idl_txn *ovs_idl_txn, - const struct ovsrec_open_vswitch *cfg, - const char *bridge_name) + const struct ovsrec_open_vswitch_table *ovs_table) { if (!ovs_idl_txn) { return NULL; } + const struct ovsrec_open_vswitch *cfg; + cfg = ovsrec_open_vswitch_table_first(ovs_table); + if (!cfg) { + return NULL; + } + const char *bridge_name = br_int_name(cfg); + ovsdb_idl_txn_add_comment(ovs_idl_txn, "ovn-controller: creating integration bridge '%s'", bridge_name); @@ -241,8 +254,7 @@ create_br_int(struct ovsdb_idl_txn *ovs_idl_txn, } static const struct ovsrec_bridge * -get_br_int(struct ovsdb_idl_txn *ovs_idl_txn, - const struct ovsrec_bridge_table *bridge_table, +get_br_int(const struct ovsrec_bridge_table *bridge_table, const struct ovsrec_open_vswitch_table *ovs_table) { const struct ovsrec_open_vswitch *cfg; @@ -251,14 +263,7 @@ get_br_int(struct ovsdb_idl_txn *ovs_idl_txn, return NULL; } - const char *br_int_name = smap_get_def(&cfg->external_ids, "ovn-bridge", - DEFAULT_BRIDGE_NAME); - - const struct ovsrec_bridge *br = get_bridge(bridge_table, br_int_name); - if (!br) { - return create_br_int(ovs_idl_txn, cfg, br_int_name); - } - return br; + return get_bridge(bridge_table, br_int_name(cfg)); } static const char * @@ -471,11 +476,8 @@ restore_ct_zones(const struct ovsrec_bridge_table *bridge_table, return; } - const char *br_int_name = smap_get_def(&cfg->external_ids, "ovn-bridge", - DEFAULT_BRIDGE_NAME); - const struct ovsrec_bridge *br_int; - br_int = get_bridge(bridge_table, br_int_name); + br_int = get_bridge(bridge_table, br_int_name(cfg)); if (!br_int) { /* If the integration bridge hasn't been defined, assume that * any existing ct-zone definitions aren't valid. */ @@ -544,6 +546,433 @@ ctrl_register_ovs_idl(struct ovsdb_idl *ovs_idl) physical_register_ovs_idl(ovs_idl); } +#define SB_NODES \ + SB_NODE(chassis, "chassis") \ + SB_NODE(encap, "encap") \ + SB_NODE(address_set, "address_set") \ + SB_NODE(port_group, "port_group") \ + SB_NODE(multicast_group, "multicast_group") \ + SB_NODE(datapath_binding, "datapath_binding") \ + SB_NODE(port_binding, "port_binding") \ + SB_NODE(mac_binding, "mac_binding") \ + SB_NODE(logical_flow, "logical_flow") \ + SB_NODE(dhcp_options, "dhcp_options") \ + SB_NODE(dhcpv6_options, "dhcpv6_options") \ + SB_NODE(dns, "dns") \ + SB_NODE(gateway_chassis, "gateway_chassis") + +enum sb_engine_node { +#define SB_NODE(NAME, NAME_STR) SB_##NAME, + SB_NODES +#undef SB_NODE +}; + +const char *sb_engine_node_names[] = { +#define SB_NODE(NAME, NAME_STR) "SB_"NAME_STR, + SB_NODES +#undef SB_NODE +}; + +#define SB_NODE_NAME(NAME) sb_engine_node_names[SB_##NAME] + +#define SB_NODE(NAME, NAME_STR) ENGINE_FUNC_SB(NAME); + SB_NODES +#undef SB_NODE + +#define OVS_NODES \ + OVS_NODE(open_vswitch, "open_vswitch") \ + OVS_NODE(bridge, "bridge") \ + OVS_NODE(port, "port") \ + OVS_NODE(qos, "qos") \ + OVS_NODE(interface, "interface") + +enum ovs_engine_node { +#define OVS_NODE(NAME, NAME_STR) OVS_##NAME, + OVS_NODES +#undef OVS_NODE +}; + +const char *ovs_engine_node_names[] = { +#define OVS_NODE(NAME, NAME_STR) "OVS_"NAME_STR, + OVS_NODES +#undef OVS_NODE +}; + +#define OVS_NODE_NAME(NAME) ovs_engine_node_names[OVS_##NAME] + +#define OVS_NODE(NAME, NAME_STR) ENGINE_FUNC_OVS(NAME); + OVS_NODES +#undef OVS_NODE + + +struct ed_type_runtime_data { + /* Contains "struct local_datapath" nodes. */ + struct hmap local_datapaths; + + /* Contains the name of each logical port resident on the local + * hypervisor. These logical ports include the VIFs (and their child + * logical ports, if any) that belong to VMs running on the hypervisor, + * l2gateway ports for which options:l2gateway-chassis designates the + * local hypervisor, and localnet ports. */ + struct sset local_lports; + + /* Contains the same ports as local_lports, but in the format: + * _ */ + struct sset local_lport_ids; + struct sset active_tunnels; + struct shash addr_sets; + struct shash port_groups; + + /* connection tracking zones. */ + unsigned long ct_zone_bitmap[BITMAP_N_LONGS(MAX_CT_ZONES)]; + struct shash pending_ct_zones; + struct simap ct_zones; +}; + +static void +en_runtime_data_init(struct engine_node *node) +{ + struct ed_type_runtime_data *data = + (struct ed_type_runtime_data *)node->data; + struct ovsrec_open_vswitch_table *ovs_table = + (struct ovsrec_open_vswitch_table *)EN_OVSDB_GET( + engine_get_input("OVS_open_vswitch", node)); + struct ovsrec_bridge_table *bridge_table = + (struct ovsrec_bridge_table *)EN_OVSDB_GET( + engine_get_input("OVS_bridge", node)); + hmap_init(&data->local_datapaths); + sset_init(&data->local_lports); + sset_init(&data->local_lport_ids); + sset_init(&data->active_tunnels); + shash_init(&data->addr_sets); + shash_init(&data->port_groups); + shash_init(&data->pending_ct_zones); + simap_init(&data->ct_zones); + + /* Initialize connection tracking zones. */ + memset(data->ct_zone_bitmap, 0, sizeof data->ct_zone_bitmap); + bitmap_set1(data->ct_zone_bitmap, 0); /* Zone 0 is reserved. */ + restore_ct_zones(bridge_table, ovs_table, + &data->ct_zones, data->ct_zone_bitmap); +} + +static void +en_runtime_data_cleanup(struct engine_node *node) +{ + struct ed_type_runtime_data *data = + (struct ed_type_runtime_data *)node->data; + + expr_const_sets_destroy(&data->addr_sets); + shash_destroy(&data->addr_sets); + expr_const_sets_destroy(&data->port_groups); + shash_destroy(&data->port_groups); + + sset_destroy(&data->local_lports); + sset_destroy(&data->local_lport_ids); + sset_destroy(&data->active_tunnels); + struct local_datapath *cur_node, *next_node; + HMAP_FOR_EACH_SAFE (cur_node, next_node, hmap_node, + &data->local_datapaths) { + free(cur_node->peer_dps); + hmap_remove(&data->local_datapaths, &cur_node->hmap_node); + free(cur_node); + } + hmap_destroy(&data->local_datapaths); + + simap_destroy(&data->ct_zones); + shash_destroy(&data->pending_ct_zones); +} + +static void +en_runtime_data_run(struct engine_node *node) +{ + struct ed_type_runtime_data *data = + (struct ed_type_runtime_data *)node->data; + struct hmap *local_datapaths = &data->local_datapaths; + struct sset *local_lports = &data->local_lports; + struct sset *local_lport_ids = &data->local_lport_ids; + struct sset *active_tunnels = &data->active_tunnels; + struct shash *addr_sets = &data->addr_sets; + struct shash *port_groups = &data->port_groups; + unsigned long *ct_zone_bitmap = data->ct_zone_bitmap; + struct shash *pending_ct_zones = &data->pending_ct_zones; + struct simap *ct_zones = &data->ct_zones; + + static bool first_run = true; + if (first_run) { + /* don't cleanup since there is no data yet */ + first_run = false; + } else { + struct local_datapath *cur_node, *next_node; + HMAP_FOR_EACH_SAFE (cur_node, next_node, hmap_node, local_datapaths) { + free(cur_node->peer_dps); + hmap_remove(local_datapaths, &cur_node->hmap_node); + free(cur_node); + } + hmap_clear(local_datapaths); + sset_destroy(local_lports); + sset_destroy(local_lport_ids); + sset_destroy(active_tunnels); + expr_const_sets_destroy(addr_sets); + expr_const_sets_destroy(port_groups); + sset_init(local_lports); + sset_init(local_lport_ids); + sset_init(active_tunnels); + } + + struct ovsrec_open_vswitch_table *ovs_table = + (struct ovsrec_open_vswitch_table *)EN_OVSDB_GET( + engine_get_input("OVS_open_vswitch", node)); + struct ovsrec_bridge_table *bridge_table = + (struct ovsrec_bridge_table *)EN_OVSDB_GET( + engine_get_input("OVS_bridge", node)); + const char *chassis_id = get_chassis_id(ovs_table); + const struct ovsrec_bridge *br_int = get_br_int(bridge_table, ovs_table); + + ovs_assert(br_int && chassis_id); + + struct ovsdb_idl_index *sbrec_chassis_by_name = + engine_ovsdb_node_get_index( + engine_get_input("SB_chassis", node), + "name"); + + const struct sbrec_chassis *chassis + = chassis_lookup_by_name(sbrec_chassis_by_name, chassis_id); + ovs_assert(chassis); + + bfd_calculate_active_tunnels(br_int, active_tunnels); + + struct ovsrec_port_table *port_table = + (struct ovsrec_port_table *)EN_OVSDB_GET( + engine_get_input("OVS_port", node)); + + struct ovsrec_qos_table *qos_table = + (struct ovsrec_qos_table *)EN_OVSDB_GET( + engine_get_input("OVS_qos", node)); + + struct sbrec_port_binding_table *pb_table = + (struct sbrec_port_binding_table *)EN_OVSDB_GET( + engine_get_input("SB_port_binding", node)); + + struct ovsdb_idl_index *sbrec_datapath_binding_by_key = + engine_ovsdb_node_get_index( + engine_get_input("SB_datapath_binding", node), + "key"); + + struct ovsdb_idl_index *sbrec_port_binding_by_name = + engine_ovsdb_node_get_index( + engine_get_input("SB_port_binding", node), + "name"); + + struct ovsdb_idl_index *sbrec_port_binding_by_datapath = + engine_ovsdb_node_get_index( + engine_get_input("SB_port_binding", node), + "datapath"); + + binding_run(engine_get_context()->ovnsb_idl_txn, + engine_get_context()->ovs_idl_txn, + sbrec_chassis_by_name, + sbrec_datapath_binding_by_key, + sbrec_port_binding_by_datapath, + sbrec_port_binding_by_name, + port_table, qos_table, pb_table, + br_int, chassis, + active_tunnels, local_datapaths, + local_lports, local_lport_ids); + + struct sbrec_address_set_table *as_table = + (struct sbrec_address_set_table *)EN_OVSDB_GET( + engine_get_input("SB_address_set", node)); + addr_sets_init(as_table, addr_sets); + + struct sbrec_port_group_table *pg_table = + (struct sbrec_port_group_table *)EN_OVSDB_GET( + engine_get_input("SB_port_group", node)); + port_groups_init(pg_table, port_groups); + + update_ct_zones(local_lports, local_datapaths, ct_zones, + ct_zone_bitmap, pending_ct_zones); + + node->changed = true; +} + +struct ed_type_mff_ovn_geneve { + enum mf_field_id mff_ovn_geneve; +}; + +static void +en_mff_ovn_geneve_init(struct engine_node *node) +{ + struct ed_type_mff_ovn_geneve *data = + (struct ed_type_mff_ovn_geneve *)node->data; + data->mff_ovn_geneve = 0; +} + +static void +en_mff_ovn_geneve_cleanup(struct engine_node *node OVS_UNUSED) +{ +} + +static void +en_mff_ovn_geneve_run(struct engine_node *node) +{ + struct ed_type_mff_ovn_geneve *data = + (struct ed_type_mff_ovn_geneve *)node->data; + enum mf_field_id mff_ovn_geneve = ofctrl_get_mf_field_id(); + if (data->mff_ovn_geneve != mff_ovn_geneve) { + data->mff_ovn_geneve = mff_ovn_geneve; + node->changed = true; + return; + } + node->changed = false; +} + +struct ed_type_flow_output { + /* desired flows */ + struct ovn_desired_flow_table flow_table; + /* group ids for load balancing */ + struct ovn_extend_table group_table; + /* meter ids for QoS */ + struct ovn_extend_table meter_table; + /* conjunction id offset */ + uint32_t conj_id_ofs; +}; + +static void +en_flow_output_init(struct engine_node *node) +{ + struct ed_type_flow_output *data = + (struct ed_type_flow_output *)node->data; + ovn_desired_flow_table_init(&data->flow_table); + ovn_extend_table_init(&data->group_table); + ovn_extend_table_init(&data->meter_table); + data->conj_id_ofs = 1; +} + +static void +en_flow_output_cleanup(struct engine_node *node) +{ + struct ed_type_flow_output *data = + (struct ed_type_flow_output *)node->data; + ovn_desired_flow_table_destroy(&data->flow_table); + ovn_extend_table_destroy(&data->group_table); + ovn_extend_table_destroy(&data->meter_table); +} + +static void +en_flow_output_run(struct engine_node *node) +{ + struct ed_type_runtime_data *rt_data = + (struct ed_type_runtime_data *)engine_get_input( + "runtime_data", node)->data; + struct hmap *local_datapaths = &rt_data->local_datapaths; + struct sset *local_lports = &rt_data->local_lports; + struct sset *local_lport_ids = &rt_data->local_lport_ids; + struct sset *active_tunnels = &rt_data->active_tunnels; + struct shash *addr_sets = &rt_data->addr_sets; + struct shash *port_groups = &rt_data->port_groups; + struct simap *ct_zones = &rt_data->ct_zones; + + struct ed_type_mff_ovn_geneve *ed_mff_ovn_geneve = + (struct ed_type_mff_ovn_geneve *)engine_get_input( + "mff_ovn_geneve", node)->data; + enum mf_field_id mff_ovn_geneve = ed_mff_ovn_geneve->mff_ovn_geneve; + + struct ovsrec_open_vswitch_table *ovs_table = + (struct ovsrec_open_vswitch_table *)EN_OVSDB_GET( + engine_get_input("OVS_open_vswitch", node)); + struct ovsrec_bridge_table *bridge_table = + (struct ovsrec_bridge_table *)EN_OVSDB_GET( + engine_get_input("OVS_bridge", node)); + const struct ovsrec_bridge *br_int = get_br_int(bridge_table, ovs_table); + const char *chassis_id = get_chassis_id(ovs_table); + + struct ovsdb_idl_index *sbrec_chassis_by_name = + engine_ovsdb_node_get_index( + engine_get_input("SB_chassis", node), + "name"); + const struct sbrec_chassis *chassis = NULL; + if (chassis_id) { + chassis = chassis_lookup_by_name(sbrec_chassis_by_name, chassis_id); + } + + ovs_assert(br_int && chassis); + + struct ed_type_flow_output *fo = + (struct ed_type_flow_output *)node->data; + struct ovn_desired_flow_table *flow_table = &fo->flow_table; + struct ovn_extend_table *group_table = &fo->group_table; + struct ovn_extend_table *meter_table = &fo->meter_table; + uint32_t *conj_id_ofs = &fo->conj_id_ofs; + + static bool first_run = true; + if (first_run) { + first_run = false; + } else { + ovn_desired_flow_table_clear(flow_table); + ovn_extend_table_clear(group_table, false /* desired */); + ovn_extend_table_clear(meter_table, false /* desired */); + } + + struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath = + engine_ovsdb_node_get_index( + engine_get_input("SB_multicast_group", node), + "name_datapath"); + + struct ovsdb_idl_index *sbrec_port_binding_by_name = + engine_ovsdb_node_get_index( + engine_get_input("SB_port_binding", node), + "name"); + + struct sbrec_dhcp_options_table *dhcp_table = + (struct sbrec_dhcp_options_table *)EN_OVSDB_GET( + engine_get_input("SB_dhcp_options", node)); + + struct sbrec_dhcpv6_options_table *dhcpv6_table = + (struct sbrec_dhcpv6_options_table *)EN_OVSDB_GET( + engine_get_input("SB_dhcpv6_options", node)); + + struct sbrec_logical_flow_table *logical_flow_table = + (struct sbrec_logical_flow_table *)EN_OVSDB_GET( + engine_get_input("SB_logical_flow", node)); + + struct sbrec_mac_binding_table *mac_binding_table = + (struct sbrec_mac_binding_table *)EN_OVSDB_GET( + engine_get_input("SB_mac_binding", node)); + + *conj_id_ofs = 1; + lflow_run(sbrec_chassis_by_name, + sbrec_multicast_group_by_name_datapath, + sbrec_port_binding_by_name, + dhcp_table, dhcpv6_table, + logical_flow_table, + mac_binding_table, + chassis, local_datapaths, addr_sets, + port_groups, active_tunnels, local_lport_ids, + flow_table, group_table, meter_table, conj_id_ofs); + + struct sbrec_multicast_group_table *multicast_group_table = + (struct sbrec_multicast_group_table *)EN_OVSDB_GET( + engine_get_input("SB_multicast_group", node)); + + struct sbrec_port_binding_table *port_binding_table = + (struct sbrec_port_binding_table *)EN_OVSDB_GET( + engine_get_input("SB_port_binding", node)); + + physical_run( + sbrec_chassis_by_name, + sbrec_port_binding_by_name, + multicast_group_table, + port_binding_table, + mff_ovn_geneve, + br_int, chassis, ct_zones, + local_datapaths, local_lports, + active_tunnels, + flow_table); + + node->changed = true; +} + struct ovn_controller_exit_args { bool *exiting; bool *restart; @@ -573,21 +1002,8 @@ main(int argc, char *argv[]) unixctl_command_register("exit", "", 0, 1, ovn_controller_exit, &exit_args); - /* Initialize group ids for loadbalancing. */ - struct ovn_extend_table group_table; - ovn_extend_table_init(&group_table); - unixctl_command_register("group-table-list", "", 0, 0, - group_table_list, &group_table); - - /* Initialize meter ids for QoS. */ - struct ovn_extend_table meter_table; - ovn_extend_table_init(&meter_table); - unixctl_command_register("meter-table-list", "", 0, 0, - meter_table_list, &meter_table); - daemonize_complete(); - ofctrl_init(&group_table, &meter_table); pinctrl_init(); lflow_init(); @@ -635,27 +1051,92 @@ main(int argc, char *argv[]) update_sb_monitors(ovnsb_idl_loop.idl, NULL, NULL, NULL); ovsdb_idl_get_initial_snapshot(ovnsb_idl_loop.idl); - /* Initialize connection tracking zones. */ - struct simap ct_zones = SIMAP_INITIALIZER(&ct_zones); - struct shash pending_ct_zones = SHASH_INITIALIZER(&pending_ct_zones); - unsigned long ct_zone_bitmap[BITMAP_N_LONGS(MAX_CT_ZONES)]; - memset(ct_zone_bitmap, 0, sizeof ct_zone_bitmap); - bitmap_set1(ct_zone_bitmap, 0); /* Zone 0 is reserved. */ - restore_ct_zones(ovsrec_bridge_table_get(ovs_idl_loop.idl), - ovsrec_open_vswitch_table_get(ovs_idl_loop.idl), - &ct_zones, ct_zone_bitmap); + stopwatch_create(CONTROLLER_LOOP_STOPWATCH_NAME, SW_MS); + + /* Define inc-proc-engine nodes. */ + struct ed_type_runtime_data ed_runtime_data; + struct ed_type_mff_ovn_geneve ed_mff_ovn_geneve; + struct ed_type_flow_output ed_flow_output; + + ENGINE_NODE(runtime_data, "runtime_data"); + ENGINE_NODE(mff_ovn_geneve, "mff_ovn_geneve"); + ENGINE_NODE(flow_output, "flow_output"); + +#define SB_NODE(NAME, NAME_STR) ENGINE_NODE_SB(NAME, NAME_STR); + SB_NODES +#undef SB_NODE + +#define OVS_NODE(NAME, NAME_STR) ENGINE_NODE_OVS(NAME, NAME_STR); + OVS_NODES +#undef OVS_NODE + + 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_port_binding, "name", sbrec_port_binding_by_name); + engine_ovsdb_node_add_index(&en_sb_port_binding, "key", sbrec_port_binding_by_key); + engine_ovsdb_node_add_index(&en_sb_port_binding, "datapath", sbrec_port_binding_by_datapath); + engine_ovsdb_node_add_index(&en_sb_datapath_binding, "key", sbrec_datapath_binding_by_key); + + /* Add dependencies between inc-proc-engine nodes. */ + engine_add_input(&en_flow_output, &en_runtime_data, NULL); + engine_add_input(&en_flow_output, &en_mff_ovn_geneve, NULL); + + engine_add_input(&en_flow_output, &en_ovs_open_vswitch, NULL); + engine_add_input(&en_flow_output, &en_ovs_bridge, NULL); + engine_add_input(&en_flow_output, &en_ovs_port, NULL); + engine_add_input(&en_flow_output, &en_ovs_interface, NULL); + + engine_add_input(&en_flow_output, &en_sb_chassis, NULL); + engine_add_input(&en_flow_output, &en_sb_encap, NULL); + engine_add_input(&en_flow_output, &en_sb_multicast_group, NULL); + engine_add_input(&en_flow_output, &en_sb_datapath_binding, NULL); + engine_add_input(&en_flow_output, &en_sb_port_binding, NULL); + engine_add_input(&en_flow_output, &en_sb_mac_binding, NULL); + engine_add_input(&en_flow_output, &en_sb_logical_flow, NULL); + engine_add_input(&en_flow_output, &en_sb_dhcp_options, NULL); + engine_add_input(&en_flow_output, &en_sb_dhcpv6_options, NULL); + engine_add_input(&en_flow_output, &en_sb_dns, NULL); + engine_add_input(&en_flow_output, &en_sb_gateway_chassis, NULL); + + engine_add_input(&en_runtime_data, &en_ovs_open_vswitch, NULL); + engine_add_input(&en_runtime_data, &en_ovs_bridge, NULL); + engine_add_input(&en_runtime_data, &en_ovs_port, NULL); + engine_add_input(&en_runtime_data, &en_ovs_qos, NULL); + engine_add_input(&en_runtime_data, &en_ovs_interface, NULL); + + engine_add_input(&en_runtime_data, &en_sb_chassis, NULL); + engine_add_input(&en_runtime_data, &en_sb_address_set, NULL); + engine_add_input(&en_runtime_data, &en_sb_port_group, NULL); + engine_add_input(&en_runtime_data, &en_sb_datapath_binding, NULL); + engine_add_input(&en_runtime_data, &en_sb_port_binding, NULL); + engine_add_input(&en_runtime_data, &en_sb_gateway_chassis, NULL); + + engine_init(&en_flow_output); + + ofctrl_init(&ed_flow_output.group_table, + &ed_flow_output.meter_table); + + unixctl_command_register("group-table-list", "", 0, 0, + group_table_list, &ed_flow_output.group_table); + + unixctl_command_register("meter-table-list", "", 0, 0, + meter_table_list, &ed_flow_output.meter_table); + unixctl_command_register("ct-zone-list", "", 0, 0, - ct_zone_list, &ct_zones); + ct_zone_list, &ed_runtime_data.ct_zones); struct pending_pkt pending_pkt = { .conn = NULL }; unixctl_command_register("inject-pkt", "MICROFLOW", 1, 1, inject_pkt, &pending_pkt); - stopwatch_create(CONTROLLER_LOOP_STOPWATCH_NAME, SW_MS); + uint64_t engine_run_id = 0; + uint64_t old_engine_run_id = 0; + /* Main loop. */ exiting = false; restart = false; while (!exiting) { + old_engine_run_id = engine_run_id; /* Check OVN SB database. */ char *new_ovnsb_remote = get_ovnsb_remote(ovs_idl_loop.idl); if (strcmp(ovnsb_remote, new_ovnsb_remote)) { @@ -670,59 +1151,54 @@ main(int argc, char *argv[]) struct ovsdb_idl_txn *ovnsb_idl_txn = ovsdb_idl_loop_run(&ovnsb_idl_loop); + struct engine_context eng_ctx = { + .ovs_idl_txn = ovs_idl_txn, + .ovnsb_idl_txn = ovnsb_idl_txn + }; + + engine_set_context(&eng_ctx); + update_probe_interval(ovsrec_open_vswitch_table_get(ovs_idl_loop.idl), ovnsb_remote, ovnsb_idl_loop.idl); update_ssl_config(ovsrec_ssl_table_get(ovs_idl_loop.idl)); - /* Contains "struct local_datapath" nodes. */ - struct hmap local_datapaths = HMAP_INITIALIZER(&local_datapaths); - - /* Contains the name of each logical port resident on the local - * hypervisor. These logical ports include the VIFs (and their child - * logical ports, if any) that belong to VMs running on the hypervisor, - * l2gateway ports for which options:l2gateway-chassis designates the - * local hypervisor, and localnet ports. */ - struct sset local_lports = SSET_INITIALIZER(&local_lports); - /* Contains the same ports as local_lports, but in the format: - * _ */ - struct sset local_lport_ids = SSET_INITIALIZER(&local_lport_ids); - struct sset active_tunnels = SSET_INITIALIZER(&active_tunnels); - - const struct ovsrec_bridge *br_int - = get_br_int(ovs_idl_txn, - ovsrec_bridge_table_get(ovs_idl_loop.idl), - ovsrec_open_vswitch_table_get(ovs_idl_loop.idl)); - const char *chassis_id - = get_chassis_id(ovsrec_open_vswitch_table_get(ovs_idl_loop.idl)); - + const struct ovsrec_bridge_table *bridge_table = + ovsrec_bridge_table_get(ovs_idl_loop.idl); + const struct ovsrec_open_vswitch_table *ovs_table = + ovsrec_open_vswitch_table_get(ovs_idl_loop.idl); + const struct ovsrec_bridge *br_int = get_br_int(bridge_table, + ovs_table); + if (!br_int) { + br_int = create_br_int(ovs_idl_txn, ovs_table); + } + const char *chassis_id = get_chassis_id(ovs_table); const struct sbrec_chassis *chassis = NULL; if (chassis_id) { - chassis = chassis_run(ovnsb_idl_txn, sbrec_chassis_by_name, - ovsrec_open_vswitch_table_get(ovs_idl_loop.idl), - chassis_id, br_int); - encaps_run(ovs_idl_txn, - ovsrec_bridge_table_get(ovs_idl_loop.idl), br_int, - sbrec_chassis_table_get(ovnsb_idl_loop.idl), chassis_id); - bfd_calculate_active_tunnels(br_int, &active_tunnels); - binding_run(ovnsb_idl_txn, ovs_idl_txn, sbrec_chassis_by_name, - sbrec_datapath_binding_by_key, - sbrec_port_binding_by_datapath, - sbrec_port_binding_by_name, - ovsrec_port_table_get(ovs_idl_loop.idl), - ovsrec_qos_table_get(ovs_idl_loop.idl), - sbrec_port_binding_table_get(ovnsb_idl_loop.idl), - br_int, chassis, - &active_tunnels, &local_datapaths, - &local_lports, &local_lport_ids); + const struct sbrec_chassis *chassis_ = chassis_run( + ovnsb_idl_txn, sbrec_chassis_by_name, ovs_table, + chassis_id, br_int); + + /* XXX: Query again using index instead of using return value + * directly from chassis_run(), because currently index + * implementation is not able to get data that is inserted in + * current transaction. We don't want to continue processing + * in current main loop if chassis can't be found with index + * since we are relying on this in the engine node processing. + */ + if (chassis_) { + chassis = chassis_lookup_by_name(sbrec_chassis_by_name, + chassis_id); + if (!chassis) { + VLOG_DBG("Chassis created but not found by index. run-id: " + "%"PRIu64, engine_run_id); + poll_immediate_wake(); + } + } } + if (br_int && chassis) { - struct shash addr_sets = SHASH_INITIALIZER(&addr_sets); - addr_sets_init(sbrec_address_set_table_get(ovnsb_idl_loop.idl), - &addr_sets); - struct shash port_groups = SHASH_INITIALIZER(&port_groups); - port_groups_init(sbrec_port_group_table_get(ovnsb_idl_loop.idl), - &port_groups); + ofctrl_run(br_int, &ed_runtime_data.pending_ct_zones); patch_run(ovs_idl_txn, ovsrec_bridge_table_get(ovs_idl_loop.idl), @@ -730,10 +1206,30 @@ main(int argc, char *argv[]) ovsrec_port_table_get(ovs_idl_loop.idl), sbrec_port_binding_table_get(ovnsb_idl_loop.idl), br_int, chassis); - - enum mf_field_id mff_ovn_geneve = ofctrl_run(br_int, - &pending_ct_zones); - + encaps_run(ovs_idl_txn, + bridge_table, br_int, + sbrec_chassis_table_get(ovnsb_idl_loop.idl), + chassis_id); + + stopwatch_start(CONTROLLER_LOOP_STOPWATCH_NAME, + time_msec()); + engine_run(&en_flow_output, ++engine_run_id); + stopwatch_stop(CONTROLLER_LOOP_STOPWATCH_NAME, + time_msec()); + if (ovs_idl_txn) { + commit_ct_zones(br_int, &ed_runtime_data.pending_ct_zones); + bfd_run(sbrec_chassis_by_name, + sbrec_port_binding_by_datapath, + ovsrec_interface_table_get(ovs_idl_loop.idl), + br_int, chassis, + &ed_runtime_data.local_datapaths); + } + ofctrl_put(&ed_flow_output.flow_table, + &ed_runtime_data.pending_ct_zones, + sbrec_meter_table_get(ovnsb_idl_loop.idl), + get_nb_cfg(sbrec_sb_global_table_get( + ovnsb_idl_loop.idl)), + en_flow_output.changed); pinctrl_run(ovnsb_idl_txn, sbrec_chassis_by_name, sbrec_datapath_binding_by_key, sbrec_port_binding_by_datapath, @@ -742,107 +1238,60 @@ main(int argc, char *argv[]) sbrec_mac_binding_by_lport_ip, sbrec_dns_table_get(ovnsb_idl_loop.idl), br_int, chassis, - &local_datapaths, &active_tunnels); - update_ct_zones(&local_lports, &local_datapaths, &ct_zones, - ct_zone_bitmap, &pending_ct_zones); - if (ovs_idl_txn) { - if (ofctrl_can_put()) { - stopwatch_start(CONTROLLER_LOOP_STOPWATCH_NAME, - time_msec()); - - commit_ct_zones(br_int, &pending_ct_zones); - - struct hmap flow_table = HMAP_INITIALIZER(&flow_table); - lflow_run(sbrec_chassis_by_name, - sbrec_multicast_group_by_name_datapath, - sbrec_port_binding_by_name, - sbrec_dhcp_options_table_get(ovnsb_idl_loop.idl), - sbrec_dhcpv6_options_table_get(ovnsb_idl_loop.idl), - sbrec_logical_flow_table_get(ovnsb_idl_loop.idl), - sbrec_mac_binding_table_get(ovnsb_idl_loop.idl), - chassis, - &local_datapaths, &addr_sets, - &port_groups, &active_tunnels, &local_lport_ids, - &flow_table, &group_table, &meter_table); - - if (chassis_id) { - bfd_run(sbrec_chassis_by_name, - sbrec_port_binding_by_datapath, - ovsrec_interface_table_get(ovs_idl_loop.idl), - br_int, chassis, &local_datapaths); - } - physical_run( - sbrec_chassis_by_name, - sbrec_port_binding_by_name, - sbrec_multicast_group_table_get(ovnsb_idl_loop.idl), - sbrec_port_binding_table_get(ovnsb_idl_loop.idl), - mff_ovn_geneve, - br_int, chassis, &ct_zones, - &local_datapaths, &local_lports, - &active_tunnels, - &flow_table); - - stopwatch_stop(CONTROLLER_LOOP_STOPWATCH_NAME, - time_msec()); - - ofctrl_put(&flow_table, &pending_ct_zones, - sbrec_meter_table_get(ovnsb_idl_loop.idl), - get_nb_cfg(sbrec_sb_global_table_get( - ovnsb_idl_loop.idl))); - - hmap_destroy(&flow_table); - } - if (ovnsb_idl_txn) { - int64_t cur_cfg = ofctrl_get_cur_cfg(); - if (cur_cfg && cur_cfg != chassis->nb_cfg) { - sbrec_chassis_set_nb_cfg(chassis, cur_cfg); - } - } + &ed_runtime_data.local_datapaths, + &ed_runtime_data.active_tunnels); + + if (en_runtime_data.changed) { + update_sb_monitors(ovnsb_idl_loop.idl, chassis, + &ed_runtime_data.local_lports, + &ed_runtime_data.local_datapaths); + } + + } + if (old_engine_run_id == engine_run_id) { + if (engine_need_run(&en_flow_output)) { + VLOG_DBG("engine did not run, force recompute next time: " + "br_int %p, chassis %p", br_int, chassis); + engine_set_force_recompute(true); + poll_immediate_wake(); + } else { + VLOG_DBG("engine did not run, and it was not needed either: " + "br_int %p, chassis %p", br_int, chassis); + } + } else { + engine_set_force_recompute(false); + } + + if (ovnsb_idl_txn && chassis) { + int64_t cur_cfg = ofctrl_get_cur_cfg(); + if (cur_cfg && cur_cfg != chassis->nb_cfg) { + sbrec_chassis_set_nb_cfg(chassis, cur_cfg); } + } + - if (pending_pkt.conn) { + if (pending_pkt.conn) { + if (br_int && chassis) { char *error = ofctrl_inject_pkt(br_int, pending_pkt.flow_s, - &port_groups, &addr_sets); + &ed_runtime_data.port_groups, + &ed_runtime_data.addr_sets); if (error) { unixctl_command_reply_error(pending_pkt.conn, error); free(error); } else { unixctl_command_reply(pending_pkt.conn, NULL); } - pending_pkt.conn = NULL; - free(pending_pkt.flow_s); + } else { + VLOG_DBG("Pending_pkt conn but br_int %p or chassis %p not" + " ready. run-id: %"PRIu64, br_int, chassis, + engine_run_id); + unixctl_command_reply_error(pending_pkt.conn, + "ovn-controller not ready."); } - - update_sb_monitors(ovnsb_idl_loop.idl, chassis, - &local_lports, &local_datapaths); - - expr_const_sets_destroy(&addr_sets); - shash_destroy(&addr_sets); - expr_const_sets_destroy(&port_groups); - shash_destroy(&port_groups); - } - - /* If we haven't handled the pending packet insertion - * request, the system is not ready. */ - if (pending_pkt.conn) { - unixctl_command_reply_error(pending_pkt.conn, - "ovn-controller not ready."); pending_pkt.conn = NULL; free(pending_pkt.flow_s); } - sset_destroy(&local_lports); - sset_destroy(&local_lport_ids); - sset_destroy(&active_tunnels); - - struct local_datapath *cur_node, *next_node; - HMAP_FOR_EACH_SAFE (cur_node, next_node, hmap_node, &local_datapaths) { - free(cur_node->peer_dps); - hmap_remove(&local_datapaths, &cur_node->hmap_node); - free(cur_node); - } - hmap_destroy(&local_datapaths); - unixctl_server_run(unixctl); unixctl_server_wait(unixctl); @@ -859,10 +1308,11 @@ main(int argc, char *argv[]) if (ovsdb_idl_loop_commit_and_wait(&ovs_idl_loop) == 1) { struct shash_node *iter, *iter_next; - SHASH_FOR_EACH_SAFE(iter, iter_next, &pending_ct_zones) { + SHASH_FOR_EACH_SAFE (iter, iter_next, + &ed_runtime_data.pending_ct_zones) { struct ct_zone_pending_entry *ctzpe = iter->data; if (ctzpe->state == CT_ZONE_DB_SENT) { - shash_delete(&pending_ct_zones, iter); + shash_delete(&ed_runtime_data.pending_ct_zones, iter); free(ctzpe); } } @@ -876,6 +1326,9 @@ main(int argc, char *argv[]) } } + engine_set_context(NULL); + engine_cleanup(&en_flow_output); + /* It's time to exit. Clean up the databases if we are not restarting */ if (!restart) { bool done = false; @@ -893,8 +1346,7 @@ main(int argc, char *argv[]) const struct sbrec_port_binding_table *port_binding_table = sbrec_port_binding_table_get(ovnsb_idl_loop.idl); - const struct ovsrec_bridge *br_int = get_br_int(ovs_idl_txn, - bridge_table, + const struct ovsrec_bridge *br_int = get_br_int(bridge_table, ovs_table); const char *chassis_id = get_chassis_id(ovs_table); const struct sbrec_chassis *chassis @@ -922,12 +1374,6 @@ main(int argc, char *argv[]) ofctrl_destroy(); pinctrl_destroy(); - simap_destroy(&ct_zones); - shash_destroy(&pending_ct_zones); - - ovn_extend_table_destroy(&group_table); - ovn_extend_table_destroy(&meter_table); - ovsdb_idl_loop_destroy(&ovs_idl_loop); ovsdb_idl_loop_destroy(&ovnsb_idl_loop); diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c index a5e0ddf..c9ea2a6 100644 --- a/ovn/controller/physical.c +++ b/ovn/controller/physical.c @@ -44,6 +44,9 @@ VLOG_DEFINE_THIS_MODULE(physical); +/* UUID to identify OF flows not associated with ovsdb rows. */ +static struct uuid *hc_uuid = NULL; + void physical_register_ovs_idl(struct ovsdb_idl *ovs_idl) { @@ -190,7 +193,8 @@ get_zone_ids(const struct sbrec_port_binding *binding, static void put_local_common_flows(uint32_t dp_key, uint32_t port_key, bool nested_container, const struct zone_ids *zone_ids, - struct ofpbuf *ofpacts_p, struct hmap *flow_table) + struct ofpbuf *ofpacts_p, + struct ovn_desired_flow_table *flow_table) { struct match match; @@ -224,7 +228,7 @@ put_local_common_flows(uint32_t dp_key, uint32_t port_key, /* Resubmit to table 34. */ put_resubmit(OFTABLE_CHECK_LOOPBACK, ofpacts_p); ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 100, 0, - &match, ofpacts_p); + &match, ofpacts_p, hc_uuid); /* Table 34, Priority 100. * ======================= @@ -239,7 +243,7 @@ put_local_common_flows(uint32_t dp_key, uint32_t port_key, match_set_reg(&match, MFF_LOG_INPORT - MFF_REG0, port_key); match_set_reg(&match, MFF_LOG_OUTPORT - MFF_REG0, port_key); ofctrl_add_flow(flow_table, OFTABLE_CHECK_LOOPBACK, 100, 0, - &match, ofpacts_p); + &match, ofpacts_p, hc_uuid); /* Table 64, Priority 100. * ======================= @@ -263,7 +267,7 @@ put_local_common_flows(uint32_t dp_key, uint32_t port_key, put_resubmit(OFTABLE_LOG_TO_PHY, ofpacts_p); put_stack(MFF_IN_PORT, ofpact_put_STACK_POP(ofpacts_p)); ofctrl_add_flow(flow_table, OFTABLE_SAVE_INPORT, 100, 0, - &match, ofpacts_p); + &match, ofpacts_p, hc_uuid); } static void @@ -299,8 +303,8 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name, const struct hmap *local_datapaths, const struct sbrec_port_binding *binding, const struct sbrec_chassis *chassis, - struct ofpbuf *ofpacts_p, - struct hmap *flow_table) + struct ovn_desired_flow_table *flow_table, + struct ofpbuf *ofpacts_p) { uint32_t dp_key = binding->datapath->tunnel_key; uint32_t port_key = binding->tunnel_key; @@ -328,8 +332,8 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name, } struct zone_ids binding_zones = get_zone_ids(binding, ct_zones); - put_local_common_flows(dp_key, port_key, false, &binding_zones, - ofpacts_p, flow_table); + put_local_common_flows(dp_key, port_key, false, + &binding_zones, ofpacts_p, flow_table); match_init_catchall(&match); ofpbuf_clear(ofpacts_p); @@ -356,7 +360,7 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name, ofpact_finish_CLONE(ofpacts_p, &clone); ofctrl_add_flow(flow_table, OFTABLE_LOG_TO_PHY, 100, 0, - &match, ofpacts_p); + &match, ofpacts_p, hc_uuid); return; } @@ -425,7 +429,7 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name, } ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 100, 0, - &match, ofpacts_p); + &match, ofpacts_p, hc_uuid); goto out; } @@ -523,8 +527,8 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name, */ struct zone_ids zone_ids = get_zone_ids(binding, ct_zones); - put_local_common_flows(dp_key, port_key, nested_container, &zone_ids, - ofpacts_p, flow_table); + put_local_common_flows(dp_key, port_key, nested_container, + &zone_ids, ofpacts_p, flow_table); /* Table 0, Priority 150 and 100. * ============================== @@ -568,7 +572,7 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name, /* Resubmit to first logical ingress pipeline table. */ put_resubmit(OFTABLE_LOG_INGRESS_PIPELINE, ofpacts_p); ofctrl_add_flow(flow_table, OFTABLE_PHY_TO_LOG, - tag ? 150 : 100, 0, &match, ofpacts_p); + tag ? 150 : 100, 0, &match, ofpacts_p, hc_uuid); if (!tag && (!strcmp(binding->type, "localnet") || !strcmp(binding->type, "l2gateway"))) { @@ -578,7 +582,7 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name, * action. */ ofpbuf_pull(ofpacts_p, ofpacts_orig_size); match_set_dl_tci_masked(&match, 0, htons(VLAN_CFI)); - ofctrl_add_flow(flow_table, 0, 100, 0, &match, ofpacts_p); + ofctrl_add_flow(flow_table, 0, 100, 0, &match, ofpacts_p, hc_uuid); } /* Table 65, Priority 100. @@ -606,7 +610,7 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name, ofpact_put_STRIP_VLAN(ofpacts_p); } ofctrl_add_flow(flow_table, OFTABLE_LOG_TO_PHY, 100, 0, - &match, ofpacts_p); + &match, ofpacts_p, hc_uuid); } else if (!tun && !is_ha_remote) { /* Remote port connected by localnet port */ /* Table 33, priority 100. @@ -629,7 +633,7 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name, /* Resubmit to table 33. */ put_resubmit(OFTABLE_LOCAL_OUTPUT, ofpacts_p); ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 100, 0, - &match, ofpacts_p); + &match, ofpacts_p, hc_uuid); } else { /* Remote port connected by tunnel */ @@ -720,7 +724,7 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name, ofpact_finish_BUNDLE(ofpacts_p, &bundle); } ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 100, 0, - &match, ofpacts_p); + &match, ofpacts_p, hc_uuid); } out: if (gateway_chassis) { @@ -736,7 +740,7 @@ consider_mc_group(enum mf_field_id mff_ovn_geneve, const struct sbrec_multicast_group *mc, struct ofpbuf *ofpacts_p, struct ofpbuf *remote_ofpacts_p, - struct hmap *flow_table) + struct ovn_desired_flow_table *flow_table) { uint32_t dp_key = mc->datapath->tunnel_key; if (!get_local_datapath(local_datapaths, dp_key)) { @@ -812,7 +816,7 @@ consider_mc_group(enum mf_field_id mff_ovn_geneve, put_load(mc->tunnel_key, MFF_LOG_OUTPORT, 0, 32, ofpacts_p); ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 100, 0, - &match, ofpacts_p); + &match, ofpacts_p, hc_uuid); } /* Table 32, priority 100. @@ -850,7 +854,7 @@ consider_mc_group(enum mf_field_id mff_ovn_geneve, put_resubmit(OFTABLE_LOCAL_OUTPUT, remote_ofpacts_p); } ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 100, 0, - &match, remote_ofpacts_p); + &match, remote_ofpacts_p, hc_uuid); } } sset_destroy(&remote_chassis); @@ -879,8 +883,13 @@ physical_run(struct ovsdb_idl_index *sbrec_chassis_by_name, const struct hmap *local_datapaths, const struct sset *local_lports, const struct sset *active_tunnels, - struct hmap *flow_table) + struct ovn_desired_flow_table *flow_table) { + if (!hc_uuid) { + hc_uuid = xmalloc(sizeof(struct uuid)); + uuid_generate(hc_uuid); + } + /* This bool tracks physical mapping changes. */ bool physical_map_changed = false; @@ -1004,7 +1013,7 @@ physical_run(struct ovsdb_idl_index *sbrec_chassis_by_name, mff_ovn_geneve, ct_zones, active_tunnels, local_datapaths, binding, chassis, - &ofpacts, flow_table); + flow_table, &ofpacts); } /* Handle output to multicast groups, in tables 32 and 33. */ @@ -1054,7 +1063,7 @@ physical_run(struct ovsdb_idl_index *sbrec_chassis_by_name, put_resubmit(OFTABLE_LOCAL_OUTPUT, &ofpacts); ofctrl_add_flow(flow_table, OFTABLE_PHY_TO_LOG, 100, 0, &match, - &ofpacts); + &ofpacts, hc_uuid); } /* Add flows for VXLAN encapsulations. Due to the limited amount of @@ -1087,7 +1096,7 @@ physical_run(struct ovsdb_idl_index *sbrec_chassis_by_name, put_resubmit(OFTABLE_LOG_INGRESS_PIPELINE, &ofpacts); ofctrl_add_flow(flow_table, OFTABLE_PHY_TO_LOG, 100, 0, &match, - &ofpacts); + &ofpacts, hc_uuid); } } @@ -1108,7 +1117,7 @@ physical_run(struct ovsdb_idl_index *sbrec_chassis_by_name, ofpbuf_clear(&ofpacts); put_resubmit(OFTABLE_LOCAL_OUTPUT, &ofpacts); ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 150, 0, - &match, &ofpacts); + &match, &ofpacts, hc_uuid); /* Table 32, priority 150. * ======================= @@ -1122,7 +1131,7 @@ physical_run(struct ovsdb_idl_index *sbrec_chassis_by_name, ofpbuf_clear(&ofpacts); put_resubmit(OFTABLE_LOCAL_OUTPUT, &ofpacts); ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 150, 0, - &match, &ofpacts); + &match, &ofpacts, hc_uuid); /* Table 32, priority 150. * ======================= @@ -1145,7 +1154,7 @@ physical_run(struct ovsdb_idl_index *sbrec_chassis_by_name, match_set_reg(&match, MFF_LOG_INPORT - MFF_REG0, pb->tunnel_key); match_set_metadata(&match, htonll(pb->datapath->tunnel_key)); ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 150, 0, - &match, &ofpacts); + &match, &ofpacts, hc_uuid); } } @@ -1157,7 +1166,8 @@ physical_run(struct ovsdb_idl_index *sbrec_chassis_by_name, match_init_catchall(&match); ofpbuf_clear(&ofpacts); put_resubmit(OFTABLE_LOCAL_OUTPUT, &ofpacts); - ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 0, 0, &match, &ofpacts); + ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 0, 0, &match, &ofpacts, + hc_uuid); /* Table 34, Priority 0. * ======================= @@ -1172,7 +1182,7 @@ physical_run(struct ovsdb_idl_index *sbrec_chassis_by_name, } put_resubmit(OFTABLE_LOG_EGRESS_PIPELINE, &ofpacts); ofctrl_add_flow(flow_table, OFTABLE_CHECK_LOOPBACK, 0, 0, &match, - &ofpacts); + &ofpacts, hc_uuid); /* Table 64, Priority 0. * ======================= @@ -1182,7 +1192,8 @@ physical_run(struct ovsdb_idl_index *sbrec_chassis_by_name, match_init_catchall(&match); ofpbuf_clear(&ofpacts); put_resubmit(OFTABLE_LOG_TO_PHY, &ofpacts); - ofctrl_add_flow(flow_table, OFTABLE_SAVE_INPORT, 0, 0, &match, &ofpacts); + ofctrl_add_flow(flow_table, OFTABLE_SAVE_INPORT, 0, 0, &match, &ofpacts, + hc_uuid); ofpbuf_uninit(&ofpacts); diff --git a/ovn/controller/physical.h b/ovn/controller/physical.h index a7a4def..1dd2b9d 100644 --- a/ovn/controller/physical.h +++ b/ovn/controller/physical.h @@ -54,6 +54,6 @@ void physical_run(struct ovsdb_idl_index *sbrec_chassis_by_name, const struct hmap *local_datapaths, const struct sset *local_lports, const struct sset *active_tunnels, - struct hmap *flow_table); + struct ovn_desired_flow_table *); #endif /* ovn/physical.h */ diff --git a/ovn/lib/actions.c b/ovn/lib/actions.c index bc1a200..083d1ca 100644 --- a/ovn/lib/actions.c +++ b/ovn/lib/actions.c @@ -1051,7 +1051,8 @@ encode_CT_LB(const struct ovnact_ct_lb *cl, recirc_table, zone_reg); } - table_id = ovn_extend_table_assign_id(ep->group_table, ds_cstr(&ds)); + table_id = ovn_extend_table_assign_id(ep->group_table, ds_cstr(&ds), + ep->lflow_uuid); ds_destroy(&ds); if (table_id == EXT_TABLE_ID_INVALID) { return; @@ -2177,7 +2178,8 @@ encode_LOG(const struct ovnact_log *log, uint32_t meter_id = NX_CTLR_NO_METER; if (log->meter) { - meter_id = ovn_extend_table_assign_id(ep->meter_table, log->meter); + meter_id = ovn_extend_table_assign_id(ep->meter_table, log->meter, + ep->lflow_uuid); if (meter_id == EXT_TABLE_ID_INVALID) { VLOG_WARN("log specified unknown meter: %"PRIu32, meter_id); return; @@ -2270,7 +2272,8 @@ encode_SET_METER(const struct ovnact_set_meter *cl, "rate=%"PRId64"", cl->rate); } - table_id = ovn_extend_table_assign_id(ep->meter_table, name); + table_id = ovn_extend_table_assign_id(ep->meter_table, name, + ep->lflow_uuid); free(name); if (table_id == EXT_TABLE_ID_INVALID) { return; diff --git a/ovn/lib/extend-table.c b/ovn/lib/extend-table.c index 511d1a8..2825eec 100644 --- a/ovn/lib/extend-table.c +++ b/ovn/lib/extend-table.c @@ -19,6 +19,7 @@ #include "bitmap.h" #include "hash.h" +#include "lib/uuid.h" #include "openvswitch/vlog.h" #include "ovn/lib/extend-table.h" @@ -91,9 +92,10 @@ ovn_extend_table_clear(struct ovn_extend_table *table, bool existing) } } +/* Remove an entry from existing table */ void -ovn_extend_table_remove(struct ovn_extend_table *table, - struct ovn_extend_table_info *existing) +ovn_extend_table_remove_existing(struct ovn_extend_table *table, + struct ovn_extend_table_info *existing) { /* Remove 'existing' from 'groups->existing' */ hmap_remove(&table->existing, &existing->hmap_node); @@ -104,21 +106,50 @@ ovn_extend_table_remove(struct ovn_extend_table *table, free(existing); } +/* Remove entries in desired table that are created by the lflow_uuid */ void -ovn_extend_table_move(struct ovn_extend_table *table) +ovn_extend_table_remove_desired(struct ovn_extend_table *table, + const struct uuid *lflow_uuid) +{ + struct ovn_extend_table_info *e, *next_e; + HMAP_FOR_EACH_SAFE (e, next_e, hmap_node, &table->desired) { + if (uuid_equals(&e->lflow_uuid, lflow_uuid)) { + hmap_remove(&table->desired, &e->hmap_node); + free(e->name); + if (e->new_table_id) { + bitmap_set0(table->table_ids, e->table_id); + } + free(e); + } + } + +} + +static struct ovn_extend_table_info* +ovn_extend_info_clone(struct ovn_extend_table_info *source) +{ + struct ovn_extend_table_info *clone = xmalloc(sizeof *clone); + clone->name = xstrdup(source->name); + clone->table_id = source->table_id; + clone->new_table_id = source->new_table_id; + clone->hmap_node.hash = source->hmap_node.hash; + clone->lflow_uuid = source->lflow_uuid; + return clone; +} + +void +ovn_extend_table_sync(struct ovn_extend_table *table) { struct ovn_extend_table_info *desired, *next; - /* Move the contents of desired to existing. */ + /* Copy the contents of desired to existing. */ HMAP_FOR_EACH_SAFE (desired, next, hmap_node, &table->desired) { - hmap_remove(&table->desired, &desired->hmap_node); - if (!ovn_extend_table_lookup(&table->existing, desired)) { - hmap_insert(&table->existing, &desired->hmap_node, - desired->hmap_node.hash); - } else { - free(desired->name); - free(desired); + desired->new_table_id = false; + struct ovn_extend_table_info *clone = + ovn_extend_info_clone(desired); + hmap_insert(&table->existing, &clone->hmap_node, + clone->hmap_node.hash); } } } @@ -126,7 +157,8 @@ ovn_extend_table_move(struct ovn_extend_table *table) /* Assign a new table ID for the table information from the bitmap. * If it already exists, return the old ID. */ uint32_t -ovn_extend_table_assign_id(struct ovn_extend_table *table, const char *name) +ovn_extend_table_assign_id(struct ovn_extend_table *table, const char *name, + struct uuid lflow_uuid) { uint32_t table_id = 0, hash; struct ovn_extend_table_info *table_info; @@ -135,7 +167,8 @@ ovn_extend_table_assign_id(struct ovn_extend_table *table, const char *name) /* Check whether we have non installed but allocated group_id. */ HMAP_FOR_EACH_WITH_HASH (table_info, hmap_node, hash, &table->desired) { - if (!strcmp(table_info->name, name)) { + if (!strcmp(table_info->name, name) && + table_info->new_table_id) { return table_info->table_id; } } @@ -167,6 +200,7 @@ ovn_extend_table_assign_id(struct ovn_extend_table *table, const char *name) table_info->table_id = table_id; table_info->hmap_node.hash = hash; table_info->new_table_id = new_table_id; + table_info->lflow_uuid = lflow_uuid; hmap_insert(&table->desired, &table_info->hmap_node, table_info->hmap_node.hash); diff --git a/ovn/lib/extend-table.h b/ovn/lib/extend-table.h index e4501f2..5be13fe 100644 --- a/ovn/lib/extend-table.h +++ b/ovn/lib/extend-table.h @@ -22,6 +22,7 @@ #include "openvswitch/hmap.h" #include "openvswitch/list.h" +#include "openvswitch/uuid.h" /* Used to manage expansion tables associated with Flow table, * such as the Group Table or Meter Table. */ @@ -36,6 +37,7 @@ struct ovn_extend_table { struct ovn_extend_table_info { struct hmap_node hmap_node; char *name; /* Name for the table entity. */ + struct uuid lflow_uuid; uint32_t table_id; bool new_table_id; /* 'True' if 'table_id' was reserved from * ovn_extend_table's 'table_ids' bitmap. */ @@ -50,14 +52,18 @@ struct ovn_extend_table_info *ovn_extend_table_lookup( void ovn_extend_table_clear(struct ovn_extend_table *, bool); -void ovn_extend_table_remove(struct ovn_extend_table *, - struct ovn_extend_table_info *); +void ovn_extend_table_remove_existing(struct ovn_extend_table *, + struct ovn_extend_table_info *); -/* Move the contents of desired to existing. */ -void ovn_extend_table_move(struct ovn_extend_table *); +void ovn_extend_table_remove_desired(struct ovn_extend_table *, + const struct uuid *lflow_uuid); + +/* Copy the contents of desired to existing. */ +void ovn_extend_table_sync(struct ovn_extend_table *); uint32_t ovn_extend_table_assign_id(struct ovn_extend_table *, - const char *name); + const char *name, + struct uuid lflow_uuid); /* Iterates 'DESIRED' through all of the 'ovn_extend_table_info's in * 'TABLE'->desired that are not in 'TABLE'->existing. (The loop body From patchwork Mon Aug 13 17:48:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 957078 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="q12Z/f8y"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41q3G02QR6z9sBD for ; Tue, 14 Aug 2018 03:52:08 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 8FDA8DBB; Mon, 13 Aug 2018 17:48:38 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 7018ACBA for ; Mon, 13 Aug 2018 17:48:36 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f193.google.com (mail-pg1-f193.google.com [209.85.215.193]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id C6FEE765 for ; Mon, 13 Aug 2018 17:48:35 +0000 (UTC) Received: by mail-pg1-f193.google.com with SMTP id f1-v6so7839517pgq.12 for ; Mon, 13 Aug 2018 10:48:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=cq9zKfZ22pSBpEDqitL3DLfo4uBWk0fnTWqPnmddWC4=; b=q12Z/f8y7Cy0jP/Br/5Ss+QwyPgzSHPHkhtkvLkaYG0A4abX7UR1ngnqv/2PWigXZs N8ly30Ap4mFO2jt3U4cqigXPUhVw6JwdE2ba4DTgm1679NxE3m4KZMkt27IOVxQzq977 yatXbRhAbzhVZZLg2dGWqGnuSoWrWi6TTcrQZf4LseUsEyIzBXCW+FwsmoDzI8g6/wR3 8RMer4FbcDocTyWkSLmkwYAiDClCwVyk4NJVV1P7aEG9M9zcn/dQt+7OT/PSL82Y3MjZ gMVBszTeqKWQtapvyXCHj8C+jnR2+C8LMEvH8sJGJc/JXsVwFUnM0S/XflG+oMlBdlaT XXjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=cq9zKfZ22pSBpEDqitL3DLfo4uBWk0fnTWqPnmddWC4=; b=H2hLOTd2c+2ZGk+w0MW/IqsIJYHv5HPV/ocjBFCwCjFhYNvAT7gQ6IXrE11QuOcflj ecRDVNygkgX4/te8pv4E2+gzyOcFk/5II7Cm1s7v3vNebMBf1LdObRZ0nqHupUnwELNv U+4vxV2dDnKV6lTRMoqJYdOaLVV2do1wF7mbfpzCiai9J5989YXQ45DLi+GfGVpwtkZu eB+2A8TNtOrGwTdnIYYXdxDYxyHpkLmJ0sZEFFviDPXAtibejQZTFGIrXoA2A2cPzTA2 YB+HOF9r0Ti2Gi6XbnRxDy2oJe++XHZONisYfpPwFg+tol1xd/fVNDPZEu6G6cd/UeJX ZRzw== X-Gm-Message-State: AOUpUlGPOUOQM10/uwI+HmN/cFN1cBtny1FjZBpNFnQl0CCKmlI7Ql7p WKQpSpL8Z2b2P8QD3H3Fo/Adu+3S X-Google-Smtp-Source: AA+uWPykgYuBn0+9DG3SCpzZaBbdoWKEe89fn9Oj8guA/UhE++sji4elETfWsx4WWbjWv6OMzIgLwA== X-Received: by 2002:a63:2647:: with SMTP id m68-v6mr17958719pgm.60.1534182515213; Mon, 13 Aug 2018 10:48:35 -0700 (PDT) Received: from localhost.localdomain.localdomain ([216.113.160.70]) by smtp.gmail.com with ESMTPSA id d22-v6sm38068664pfk.69.2018.08.13.10.48.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Aug 2018 10:48:34 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Mon, 13 Aug 2018 10:48:07 -0700 Message-Id: <1534182499-75914-9-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> References: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v5 08/20] ovn-controller: Incremental logical flow processing X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org Implements change handler of flow_output for SB lflow changes. Signed-off-by: Han Zhou --- ovn/controller/lflow.c | 84 +++++++++++++++++++++++++++++++++++++++++ ovn/controller/lflow.h | 18 +++++++++ ovn/controller/ovn-controller.c | 76 ++++++++++++++++++++++++++++++++++++- 3 files changed, 177 insertions(+), 1 deletion(-) diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c index 72b1ec7..f7cb6d4 100644 --- a/ovn/controller/lflow.c +++ b/ovn/controller/lflow.c @@ -200,6 +200,90 @@ add_logical_flows( nd_ra_opts_destroy(&nd_ra_opts); } +bool +lflow_handle_changed_flows( + struct ovsdb_idl_index *sbrec_chassis_by_name, + struct ovsdb_idl_index *sbrec_multicast_group_by_name_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, + const struct sbrec_logical_flow_table *logical_flow_table, + const struct hmap *local_datapaths, + const struct sbrec_chassis *chassis, + const struct shash *addr_sets, + const struct shash *port_groups, + const struct sset *active_tunnels, + const struct sset *local_lport_ids, + struct ovn_desired_flow_table *flow_table, + struct ovn_extend_table *group_table, + struct ovn_extend_table *meter_table, + uint32_t *conj_id_ofs) +{ + bool ret = true; + const struct sbrec_logical_flow *lflow; + + struct hmap dhcp_opts = HMAP_INITIALIZER(&dhcp_opts); + struct hmap dhcpv6_opts = HMAP_INITIALIZER(&dhcpv6_opts); + const struct sbrec_dhcp_options *dhcp_opt_row; + SBREC_DHCP_OPTIONS_TABLE_FOR_EACH (dhcp_opt_row, dhcp_options_table) { + dhcp_opt_add(&dhcp_opts, dhcp_opt_row->name, dhcp_opt_row->code, + dhcp_opt_row->type); + } + + + const struct sbrec_dhcpv6_options *dhcpv6_opt_row; + SBREC_DHCPV6_OPTIONS_TABLE_FOR_EACH (dhcpv6_opt_row, + dhcpv6_options_table) { + dhcp_opt_add(&dhcpv6_opts, dhcpv6_opt_row->name, dhcpv6_opt_row->code, + dhcpv6_opt_row->type); + } + + struct hmap nd_ra_opts = HMAP_INITIALIZER(&nd_ra_opts); + nd_ra_opts_init(&nd_ra_opts); + + /* Handle removed flows first, and then other flows, so that when + * the flows being added and removed have same match conditions + * can be processed in the proper order */ + SBREC_LOGICAL_FLOW_TABLE_FOR_EACH_TRACKED (lflow, logical_flow_table) { + /* Remove any flows that should be removed. */ + if (sbrec_logical_flow_is_deleted(lflow)) { + VLOG_DBG("handle deleted lflow "UUID_FMT, + UUID_ARGS(&lflow->header_.uuid)); + ofctrl_remove_flows(flow_table, &lflow->header_.uuid); + } + } + SBREC_LOGICAL_FLOW_TABLE_FOR_EACH_TRACKED (lflow, logical_flow_table) { + if (!sbrec_logical_flow_is_deleted(lflow)) { + /* Now, add/modify existing flows. If the logical + * flow is a modification, just remove the flows + * for this row, and then add new flows. */ + if (!sbrec_logical_flow_is_new(lflow)) { + VLOG_DBG("handle updated lflow "UUID_FMT, + UUID_ARGS(&lflow->header_.uuid)); + ofctrl_remove_flows(flow_table, &lflow->header_.uuid); + } + VLOG_DBG("handle new lflow "UUID_FMT, + UUID_ARGS(&lflow->header_.uuid)); + if (!consider_logical_flow(sbrec_chassis_by_name, + sbrec_multicast_group_by_name_datapath, + sbrec_port_binding_by_name, + lflow, local_datapaths, + chassis, &dhcp_opts, &dhcpv6_opts, + &nd_ra_opts, addr_sets, port_groups, + active_tunnels, local_lport_ids, + flow_table, group_table, meter_table, + conj_id_ofs)) { + ret = false; + break; + } + } + } + dhcp_opts_destroy(&dhcp_opts); + dhcp_opts_destroy(&dhcpv6_opts); + nd_ra_opts_destroy(&nd_ra_opts); + return ret; +} + static bool update_conj_id_ofs(uint32_t *conj_id_ofs, uint32_t n_conjs) { diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h index b4120d0..31e34e2 100644 --- a/ovn/controller/lflow.h +++ b/ovn/controller/lflow.h @@ -84,6 +84,24 @@ void lflow_run(struct ovsdb_idl_index *sbrec_chassis_by_name, struct ovn_extend_table *meter_table, uint32_t *conj_id_ofs); +bool lflow_handle_changed_flows( + struct ovsdb_idl_index *sbrec_chassis_by_name, + struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath, + struct ovsdb_idl_index *sbrec_port_binding_by_name, + const struct sbrec_dhcp_options_table *, + const struct sbrec_dhcpv6_options_table *, + const struct sbrec_logical_flow_table *, + const struct hmap *local_datapaths, + const struct sbrec_chassis *, + const struct shash *addr_sets, + const struct shash *port_groups, + const struct sset *active_tunnels, + const struct sset *local_lport_ids, + struct ovn_desired_flow_table *, + struct ovn_extend_table *group_table, + struct ovn_extend_table *meter_table, + uint32_t *conj_id_ofs); + void lflow_destroy(void); #endif /* ovn/lflow.h */ diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index bfe99dd..5c24cba 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -973,6 +973,80 @@ en_flow_output_run(struct engine_node *node) node->changed = true; } +static bool +flow_output_sb_logical_flow_handler(struct engine_node *node) +{ + struct ed_type_runtime_data *data = + (struct ed_type_runtime_data *)engine_get_input( + "runtime_data", node)->data; + struct hmap *local_datapaths = &data->local_datapaths; + struct sset *local_lport_ids = &data->local_lport_ids; + struct sset *active_tunnels = &data->active_tunnels; + struct shash *addr_sets = &data->addr_sets; + struct shash *port_groups = &data->port_groups; + + struct ovsrec_open_vswitch_table *ovs_table = + (struct ovsrec_open_vswitch_table *)EN_OVSDB_GET( + engine_get_input("OVS_open_vswitch", node)); + struct ovsrec_bridge_table *bridge_table = + (struct ovsrec_bridge_table *)EN_OVSDB_GET( + engine_get_input("OVS_bridge", node)); + const struct ovsrec_bridge *br_int = get_br_int(bridge_table, ovs_table); + const char *chassis_id = get_chassis_id(ovs_table); + + struct ovsdb_idl_index *sbrec_chassis_by_name = + engine_ovsdb_node_get_index( + engine_get_input("SB_chassis", node), + "name"); + const struct sbrec_chassis *chassis = NULL; + if (chassis_id) { + chassis = chassis_lookup_by_name(sbrec_chassis_by_name, chassis_id); + } + + ovs_assert(br_int && chassis); + + struct ed_type_flow_output *fo = + (struct ed_type_flow_output *)node->data; + struct ovn_desired_flow_table *flow_table = &fo->flow_table; + struct ovn_extend_table *group_table = &fo->group_table; + struct ovn_extend_table *meter_table = &fo->meter_table; + uint32_t *conj_id_ofs = &fo->conj_id_ofs; + + struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath = + engine_ovsdb_node_get_index( + engine_get_input("SB_multicast_group", node), + "name_datapath"); + + struct ovsdb_idl_index *sbrec_port_binding_by_name = + engine_ovsdb_node_get_index( + engine_get_input("SB_port_binding", node), + "name"); + + struct sbrec_dhcp_options_table *dhcp_table = + (struct sbrec_dhcp_options_table *)EN_OVSDB_GET( + engine_get_input("SB_dhcp_options", node)); + + struct sbrec_dhcpv6_options_table *dhcpv6_table = + (struct sbrec_dhcpv6_options_table *)EN_OVSDB_GET( + engine_get_input("SB_dhcpv6_options", node)); + + struct sbrec_logical_flow_table *logical_flow_table = + (struct sbrec_logical_flow_table *)EN_OVSDB_GET( + engine_get_input("SB_logical_flow", node)); + + bool handled = lflow_handle_changed_flows(sbrec_chassis_by_name, + sbrec_multicast_group_by_name_datapath, + sbrec_port_binding_by_name, + dhcp_table, dhcpv6_table, + logical_flow_table, + local_datapaths, chassis, addr_sets, + port_groups, active_tunnels, local_lport_ids, + flow_table, group_table, meter_table, conj_id_ofs); + + node->changed = true; + return handled; +} + struct ovn_controller_exit_args { bool *exiting; bool *restart; @@ -1092,7 +1166,7 @@ main(int argc, char *argv[]) engine_add_input(&en_flow_output, &en_sb_datapath_binding, NULL); engine_add_input(&en_flow_output, &en_sb_port_binding, NULL); engine_add_input(&en_flow_output, &en_sb_mac_binding, NULL); - engine_add_input(&en_flow_output, &en_sb_logical_flow, NULL); + engine_add_input(&en_flow_output, &en_sb_logical_flow, flow_output_sb_logical_flow_handler); engine_add_input(&en_flow_output, &en_sb_dhcp_options, NULL); engine_add_input(&en_flow_output, &en_sb_dhcpv6_options, NULL); engine_add_input(&en_flow_output, &en_sb_dns, NULL); From patchwork Mon Aug 13 17:48:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 957079 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="V6W/Uc6J"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41q3GW0hRKz9sBD for ; Tue, 14 Aug 2018 03:52:35 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 57848DD9; Mon, 13 Aug 2018 17:48:39 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 08D65CBA for ; Mon, 13 Aug 2018 17:48:37 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pf1-f178.google.com (mail-pf1-f178.google.com [209.85.210.178]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 746A7765 for ; Mon, 13 Aug 2018 17:48:36 +0000 (UTC) Received: by mail-pf1-f178.google.com with SMTP id u24-v6so7981284pfn.13 for ; Mon, 13 Aug 2018 10:48:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=2uaOJvOChdzXH5wbdRNQ76CTgbTCISPWaxOmpCatHvI=; b=V6W/Uc6JPhbvNL9KltcLsRVyNbNEbY5vIrJfWNKLWrHC7tmv5xqD+B1Q0f9VPGU4t7 n6SKxenZBEDRwBMBuYnjXddTSQCC6c7k7hlp/OHutTsCrgKs1FOiYliXxlExy4Vd4Klq sYGB5yTMXuZ6Y0j/EM3pkzFYU19ceVomy2vNSDHKNweirB2O++fXUWLrUq3sIU94PqZp rBX5uKLB751WpaI/dA0ZuhtD4odKC7YDTJaYNJFk1dbLGkZiTchJnoeU5zqYeDPfcCq2 TWYKx6VOtHuEizu/NvIPEIgkrdWthc6bAX5+n57hkoGCwcDGXlOGG21a7yrMFTqJfbs+ 0GaA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=2uaOJvOChdzXH5wbdRNQ76CTgbTCISPWaxOmpCatHvI=; b=WL/Kch+M8Ru1a0D7vSutiV26HzaJjBoiEm7OZnPpUJP0fMthvOnoPr9Ecof8nN6Pkg SKUhLYlKOJltawBcTxwF+1QX+8FQgonBox2jXtowkJVAMNALHAKQctO2i1Yt/5AjCVkq OszRhEAYb/DsKbF20lxS0ZwuUOjqJykQlj1u0lEYH1FjtU0Jrzr9iIfb7DCGtW4oMKEO Ccwg9+7+qnRIGveVH6nnzqefqUY/HBkQx6LMhgl5WU3Yq1qSjxjKvpbkA+7LEsr4pVr4 dIjQt5DujVBLzdiGKXwtpYyJ8sjWgA3DGn0+NBzVWY2/6DX/IxQdgWdgb/j4R0YvqAUv j92w== X-Gm-Message-State: AOUpUlHWVf3J80M4VauPqu+u1f72mXFcSg9WcVRWUbQSKEsQSDVzCint j73+VN8rS6aKQdCHpCc3zsItHXIe X-Google-Smtp-Source: AA+uWPzzZeObm/zmR9xkxNaDFavQ291jSqImiCTEOEaTFK4GosiAv6BMqKcL0UKhIVDtseVebES1FA== X-Received: by 2002:a63:6604:: with SMTP id a4-v6mr17454400pgc.404.1534182515887; Mon, 13 Aug 2018 10:48:35 -0700 (PDT) Received: from localhost.localdomain.localdomain ([216.113.160.70]) by smtp.gmail.com with ESMTPSA id d22-v6sm38068664pfk.69.2018.08.13.10.48.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Aug 2018 10:48:35 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Mon, 13 Aug 2018 10:48:08 -0700 Message-Id: <1534182499-75914-10-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> References: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v5 09/20] ovn-controller: runtime_data change handler for SB port-binding X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org Evaluates change for SB port-binding in runtime_data node. If the port-binding change has no impact for the runtime_data it will not trigger runtime_data change. Signed-off-by: Han Zhou --- ovn/controller/binding.c | 91 +++++++++++++++++++++++++++++++++++++++++ ovn/controller/binding.h | 7 ++++ ovn/controller/ovn-controller.c | 42 ++++++++++++++++++- 3 files changed, 139 insertions(+), 1 deletion(-) diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c index a4b30cb..7ec6074 100644 --- a/ovn/controller/binding.c +++ b/ovn/controller/binding.c @@ -615,6 +615,97 @@ binding_run(struct ovsdb_idl_txn *ovnsb_idl_txn, hmap_destroy(&qos_map); } +static bool +is_our_chassis(struct ovsdb_idl_index *sbrec_chassis_by_name, + const struct sbrec_chassis *chassis_rec, + const struct sbrec_port_binding *binding_rec, + const struct sset *active_tunnels, + const struct shash *lport_to_iface, + const struct sset *local_lports) +{ + const struct ovsrec_interface *iface_rec + = shash_find_data(lport_to_iface, binding_rec->logical_port); + struct ovs_list *gateway_chassis = NULL; + + bool our_chassis = false; + if (iface_rec + || (binding_rec->parent_port && binding_rec->parent_port[0] && + sset_contains(local_lports, binding_rec->parent_port))) { + /* This port is in our chassis unless it is a localport. */ + if (strcmp(binding_rec->type, "localport")) { + our_chassis = true; + } + } else if (!strcmp(binding_rec->type, "l2gateway")) { + const char *chassis_id = smap_get(&binding_rec->options, + "l2gateway-chassis"); + our_chassis = chassis_id && !strcmp(chassis_id, chassis_rec->name); + } else if (!strcmp(binding_rec->type, "chassisredirect")) { + gateway_chassis = gateway_chassis_get_ordered(sbrec_chassis_by_name, + binding_rec); + if (gateway_chassis && + gateway_chassis_contains(gateway_chassis, chassis_rec)) { + + our_chassis = gateway_chassis_is_active( + gateway_chassis, chassis_rec, active_tunnels); + + } + gateway_chassis_destroy(gateway_chassis); + } else if (!strcmp(binding_rec->type, "l3gateway")) { + const char *chassis_id = smap_get(&binding_rec->options, + "l3gateway-chassis"); + our_chassis = chassis_id && !strcmp(chassis_id, chassis_rec->name); + } else if (!strcmp(binding_rec->type, "localnet")) { + our_chassis = false; + } + + return our_chassis; +} + +/* Returns true if port-binding changes potentially require flow changes on + * the current chassis. Returns false if we are sure there is no impact. */ +bool +binding_evaluate_port_binding_changes( + struct ovsdb_idl_index *sbrec_chassis_by_name, + const struct sbrec_port_binding_table *pb_table, + const struct ovsrec_bridge *br_int, + const struct sbrec_chassis *chassis_rec, + struct sset *active_tunnels, + struct sset *local_lports) +{ + if (!chassis_rec) { + return true; + } + + const struct sbrec_port_binding *binding_rec; + struct shash lport_to_iface = SHASH_INITIALIZER(&lport_to_iface); + struct sset egress_ifaces = SSET_INITIALIZER(&egress_ifaces); + if (br_int) { + get_local_iface_ids(br_int, &lport_to_iface, local_lports, + &egress_ifaces); + } + SBREC_PORT_BINDING_TABLE_FOR_EACH_TRACKED (binding_rec, pb_table) { + /* XXX: currently OVSDB change tracking doesn't support getting old + * data when the operation is update, so if a port-binding moved from + * this chassis to another, we would not know it with this check. + * However, if the port is unbound from this chassis, the local ovsdb + * interface table will be updated, which will trigger recompute. + * If the port is still bound on this chassis, then below check + * is_our_chassis() will take care of that case. */ + if (binding_rec->chassis == chassis_rec) { + return true; + } + if (is_our_chassis(sbrec_chassis_by_name, chassis_rec, binding_rec, + active_tunnels, &lport_to_iface, local_lports) + || !strcmp(binding_rec->type, "patch") + || !strcmp(binding_rec->type, "localport") + || !strcmp(binding_rec->type, "vtep") + || !strcmp(binding_rec->type, "localnet")) { + return true; + } + } + return false; +} + /* Returns true if the database is all cleaned up, false if more work is * required. */ bool diff --git a/ovn/controller/binding.h b/ovn/controller/binding.h index 837e109..6c62cc5 100644 --- a/ovn/controller/binding.h +++ b/ovn/controller/binding.h @@ -48,5 +48,12 @@ void binding_run(struct ovsdb_idl_txn *ovnsb_idl_txn, bool binding_cleanup(struct ovsdb_idl_txn *ovnsb_idl_txn, const struct sbrec_port_binding_table *, const struct sbrec_chassis *); +bool binding_evaluate_port_binding_changes( + struct ovsdb_idl_index *sbrec_chassis_by_name, + const struct sbrec_port_binding_table *, + const struct ovsrec_bridge *br_int, + const struct sbrec_chassis *, + struct sset *active_tunnels, + struct sset *local_lports); #endif /* ovn/binding.h */ diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 5c24cba..ba589fe 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -796,6 +796,46 @@ en_runtime_data_run(struct engine_node *node) node->changed = true; } +static bool +runtime_data_sb_port_binding_handler(struct engine_node *node) +{ + struct ed_type_runtime_data *data = + (struct ed_type_runtime_data *)node->data; + struct sset *local_lports = &data->local_lports; + struct sset *active_tunnels = &data->active_tunnels; + + struct ovsrec_open_vswitch_table *ovs_table = + (struct ovsrec_open_vswitch_table *)EN_OVSDB_GET( + engine_get_input("OVS_open_vswitch", node)); + struct ovsrec_bridge_table *bridge_table = + (struct ovsrec_bridge_table *)EN_OVSDB_GET( + engine_get_input("OVS_bridge", node)); + const char *chassis_id = get_chassis_id(ovs_table); + const struct ovsrec_bridge *br_int = get_br_int(bridge_table, ovs_table); + + ovs_assert(br_int && chassis_id); + + struct ovsdb_idl_index *sbrec_chassis_by_name = + engine_ovsdb_node_get_index( + engine_get_input("SB_chassis", node), + "name"); + + const struct sbrec_chassis *chassis + = chassis_lookup_by_name(sbrec_chassis_by_name, chassis_id); + ovs_assert(chassis); + + struct sbrec_port_binding_table *pb_table = + (struct sbrec_port_binding_table *)EN_OVSDB_GET( + engine_get_input("SB_port_binding", node)); + + bool changed = binding_evaluate_port_binding_changes( + sbrec_chassis_by_name, pb_table, + br_int, chassis, active_tunnels, + local_lports); + + return !changed; +} + struct ed_type_mff_ovn_geneve { enum mf_field_id mff_ovn_geneve; }; @@ -1182,7 +1222,7 @@ main(int argc, char *argv[]) engine_add_input(&en_runtime_data, &en_sb_address_set, NULL); engine_add_input(&en_runtime_data, &en_sb_port_group, NULL); engine_add_input(&en_runtime_data, &en_sb_datapath_binding, NULL); - engine_add_input(&en_runtime_data, &en_sb_port_binding, NULL); + engine_add_input(&en_runtime_data, &en_sb_port_binding, runtime_data_sb_port_binding_handler); engine_add_input(&en_runtime_data, &en_sb_gateway_chassis, NULL); engine_init(&en_flow_output); From patchwork Mon Aug 13 17:48:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 957080 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="VLFDLJEQ"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41q3HG6HqVz9s78 for ; Tue, 14 Aug 2018 03:53:14 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 870A3D6D; Mon, 13 Aug 2018 17:48:41 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 49996DC2 for ; Mon, 13 Aug 2018 17:48:38 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pf1-f169.google.com (mail-pf1-f169.google.com [209.85.210.169]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 3FDA67C4 for ; Mon, 13 Aug 2018 17:48:37 +0000 (UTC) Received: by mail-pf1-f169.google.com with SMTP id l9-v6so7989862pff.9 for ; Mon, 13 Aug 2018 10:48:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=4henZXUdlLbk78ZPhl72aO8ju02tHedm4e28IMlp7uk=; b=VLFDLJEQYQLA8pjOIeZw5AH03tT6Zq7ITShQom6f73386wtNEn9Irn28cLiZ6UyEj1 T9QEFKzLr7XtBQv1vDPgXJCIS51aefF+k3QtsSMaqWexKbOwDrlIglN7eNc/Lr2IPJ9m m2C7OY6WUlal+4ytXSMlWLLWWY8ADuYkE2TknAevfl9qTwcAwlOI+7NlxVEBkmhnT6gZ d3/JBgNisvBDqmQ+ESH1HrBhtrYRC/Z2pxKzVj3GGemk2SOFmXug7C6Q/g1O/4zkH/Pt v4jjPCfSSCP112spQ0iZupPF6p4QORVwy6xkw4chST5+QU3g8VTDRqAbyH90ee7t4pjC +mkA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=4henZXUdlLbk78ZPhl72aO8ju02tHedm4e28IMlp7uk=; b=ZgJD9atVW6MLhxLJShAseoOAXoOxYaLoGYqodSemEXqh+csuxpgqvxo5GKVvYLGAHj JBTmvg9AVgyAvPgfqFwa5bNIiontC6Pu97e/bmOuYVanmD9z8Hiw+omt0a8MIXUp8IHc LZktVUry8KvWDn0k/Rvy5LSSV5/W2ZZXfpXrSxuy0Zuk4D60DjxbG2an0HoN9CtvrF/5 kRHJiqdfJZ3swNdsl5ElHDPkCAJkY/m4wJFWPbgsQVrsFYSctpsupaRQPGjNqj5IKgSf aiEPbqz8WATBxKEnobqRF5Ph/WLCFsGJLGLprI5qbUbaBNJyGiUPGbHU5GdfzNMX9PrX IjQg== X-Gm-Message-State: AOUpUlECAYFSMy5GL/jfVxihWeT9MOrS1Hxrn0pL7i/G5QP05A8cayRn lK7mKvYYhG2CTsoFm8yTDdM4N+NU X-Google-Smtp-Source: AA+uWPzbaFXMTaO0W3mQ6SV3zUiKlIS9OQmLNag01FmslAv/8qXQ2UnY8jnE6ZMU+qaJ7ZFANf3zFw== X-Received: by 2002:a63:ee56:: with SMTP id n22-v6mr17191424pgk.402.1534182516564; Mon, 13 Aug 2018 10:48:36 -0700 (PDT) Received: from localhost.localdomain.localdomain ([216.113.160.70]) by smtp.gmail.com with ESMTPSA id d22-v6sm38068664pfk.69.2018.08.13.10.48.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Aug 2018 10:48:36 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Mon, 13 Aug 2018 10:48:09 -0700 Message-Id: <1534182499-75914-11-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> References: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v5 10/20] ovn-controller: port-binding incremental processing for physical flows X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org This patch implements change handler for port-binding in flow_output for physical flows computing, so that physical flow computing will be incremental. Signed-off-by: Han Zhou --- ovn/controller/ovn-controller.c | 95 ++++++++++++++++++++++++++++++++++- ovn/controller/physical.c | 106 ++++++++++++++++++++++++++-------------- ovn/controller/physical.h | 10 ++++ 3 files changed, 173 insertions(+), 38 deletions(-) diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index ba589fe..9fd2cba 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -1087,6 +1087,99 @@ flow_output_sb_logical_flow_handler(struct engine_node *node) return handled; } +static bool +flow_output_sb_port_binding_handler(struct engine_node *node) +{ + struct ed_type_runtime_data *data = + (struct ed_type_runtime_data *)engine_get_input( + "runtime_data", node)->data; + struct hmap *local_datapaths = &data->local_datapaths; + struct sset *active_tunnels = &data->active_tunnels; + struct simap *ct_zones = &data->ct_zones; + + struct ed_type_mff_ovn_geneve *ed_mff_ovn_geneve = + (struct ed_type_mff_ovn_geneve *)engine_get_input( + "mff_ovn_geneve", node)->data; + enum mf_field_id mff_ovn_geneve = ed_mff_ovn_geneve->mff_ovn_geneve; + + struct ovsrec_open_vswitch_table *ovs_table = + (struct ovsrec_open_vswitch_table *)EN_OVSDB_GET( + engine_get_input("OVS_open_vswitch", node)); + struct ovsrec_bridge_table *bridge_table = + (struct ovsrec_bridge_table *)EN_OVSDB_GET( + engine_get_input("OVS_bridge", node)); + const struct ovsrec_bridge *br_int = get_br_int(bridge_table, ovs_table); + const char *chassis_id = get_chassis_id(ovs_table); + + struct ovsdb_idl_index *sbrec_chassis_by_name = + engine_ovsdb_node_get_index( + engine_get_input("SB_chassis", node), + "name"); + const struct sbrec_chassis *chassis = NULL; + if (chassis_id) { + chassis = chassis_lookup_by_name(sbrec_chassis_by_name, chassis_id); + } + ovs_assert(br_int && chassis); + + struct ed_type_flow_output *fo = + (struct ed_type_flow_output *)node->data; + struct ovn_desired_flow_table *flow_table = &fo->flow_table; + + struct ovsdb_idl_index *sbrec_port_binding_by_name = + engine_ovsdb_node_get_index( + engine_get_input("SB_port_binding", node), + "name"); + + struct sbrec_port_binding_table *port_binding_table = + (struct sbrec_port_binding_table *)EN_OVSDB_GET( + engine_get_input("SB_port_binding", node)); + + /* XXX: now we handles port-binding changes for physical flow processing + * only, but port-binding change can have impact to logical flow + * processing, too, in below circumstances: + * + * - When a port-binding for a lport is inserted/deleted but the lflow + * using that lport doesn't change. + * + * This is likely to happen only when the lport name is used by ACL + * match condition, which is specified by user. Even in that case, when + * port is actually bound on the chassis it will trigger recompute on + * that chassis since ovs interface is updated. So the only situation + * this would have real impact is when user defines an ACL that includes + * lport that is not the ingress/egress lport, e.g.: + * + * to-lport 1000 'outport=="A" && inport=="B"' allow-related + * + * If "B" is created and bound after the ACL is created, the ACL may not + * take effect on the chassis where "A" is bound, until a recompute is + * triggered there later. + * + * - When is_chassis_resident is used in lflow. In this case the port + * binding is patch type, since this condition is used only for lrouter + * ports. In current "runtime_data" handling, port-binding changes of + * patch ports always trigger recomputing. So it is fine even if we do + * not handle it here. + * + * - When a mac-binding doesn't change but the port-binding related to + * that mac-binding is deleted. In this case the neighbor flow generated + * for the mac-binding should be deleted. This would not cause any real + * issue for now, since mac-binding change triggers recomputing. + * + * To address the above issues, we will need to maintain a mapping between + * lport names and the lflows that uses them, and reprocess the related + * lflows when a port-binding corresponding to a lport name changes. + */ + + physical_handle_port_binding_changes( + sbrec_chassis_by_name, sbrec_port_binding_by_name, + port_binding_table, mff_ovn_geneve, + chassis, ct_zones, local_datapaths, + active_tunnels, flow_table); + + node->changed = true; + return true; +} + struct ovn_controller_exit_args { bool *exiting; bool *restart; @@ -1204,7 +1297,7 @@ main(int argc, char *argv[]) engine_add_input(&en_flow_output, &en_sb_encap, NULL); engine_add_input(&en_flow_output, &en_sb_multicast_group, NULL); engine_add_input(&en_flow_output, &en_sb_datapath_binding, NULL); - engine_add_input(&en_flow_output, &en_sb_port_binding, NULL); + engine_add_input(&en_flow_output, &en_sb_port_binding, flow_output_sb_port_binding_handler); engine_add_input(&en_flow_output, &en_sb_mac_binding, NULL); engine_add_input(&en_flow_output, &en_sb_logical_flow, flow_output_sb_logical_flow_handler); engine_add_input(&en_flow_output, &en_sb_dhcp_options, NULL); diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c index c9ea2a6..1cb9f7b 100644 --- a/ovn/controller/physical.c +++ b/ovn/controller/physical.c @@ -360,7 +360,7 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name, ofpact_finish_CLONE(ofpacts_p, &clone); ofctrl_add_flow(flow_table, OFTABLE_LOG_TO_PHY, 100, 0, - &match, ofpacts_p, hc_uuid); + &match, ofpacts_p, &binding->header_.uuid); return; } @@ -429,7 +429,7 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name, } ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 100, 0, - &match, ofpacts_p, hc_uuid); + &match, ofpacts_p, &binding->header_.uuid); goto out; } @@ -572,7 +572,8 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name, /* Resubmit to first logical ingress pipeline table. */ put_resubmit(OFTABLE_LOG_INGRESS_PIPELINE, ofpacts_p); ofctrl_add_flow(flow_table, OFTABLE_PHY_TO_LOG, - tag ? 150 : 100, 0, &match, ofpacts_p, hc_uuid); + tag ? 150 : 100, 0, &match, ofpacts_p, + &binding->header_.uuid); if (!tag && (!strcmp(binding->type, "localnet") || !strcmp(binding->type, "l2gateway"))) { @@ -582,7 +583,8 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name, * action. */ ofpbuf_pull(ofpacts_p, ofpacts_orig_size); match_set_dl_tci_masked(&match, 0, htons(VLAN_CFI)); - ofctrl_add_flow(flow_table, 0, 100, 0, &match, ofpacts_p, hc_uuid); + ofctrl_add_flow(flow_table, 0, 100, 0, &match, ofpacts_p, + &binding->header_.uuid); } /* Table 65, Priority 100. @@ -610,7 +612,7 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name, ofpact_put_STRIP_VLAN(ofpacts_p); } ofctrl_add_flow(flow_table, OFTABLE_LOG_TO_PHY, 100, 0, - &match, ofpacts_p, hc_uuid); + &match, ofpacts_p, &binding->header_.uuid); } else if (!tun && !is_ha_remote) { /* Remote port connected by localnet port */ /* Table 33, priority 100. @@ -633,7 +635,7 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name, /* Resubmit to table 33. */ put_resubmit(OFTABLE_LOCAL_OUTPUT, ofpacts_p); ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 100, 0, - &match, ofpacts_p, hc_uuid); + &match, ofpacts_p, &binding->header_.uuid); } else { /* Remote port connected by tunnel */ @@ -724,7 +726,7 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name, ofpact_finish_BUNDLE(ofpacts_p, &bundle); } ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 100, 0, - &match, ofpacts_p, hc_uuid); + &match, ofpacts_p, &binding->header_.uuid); } out: if (gateway_chassis) { @@ -738,8 +740,6 @@ consider_mc_group(enum mf_field_id mff_ovn_geneve, const struct hmap *local_datapaths, const struct sbrec_chassis *chassis, const struct sbrec_multicast_group *mc, - struct ofpbuf *ofpacts_p, - struct ofpbuf *remote_ofpacts_p, struct ovn_desired_flow_table *flow_table) { uint32_t dp_key = mc->datapath->tunnel_key; @@ -759,15 +759,17 @@ consider_mc_group(enum mf_field_id mff_ovn_geneve, * - For remote ports, add the chassis to 'remote_chassis'. * * - For local ports (other than logical patch ports), add actions - * to 'ofpacts_p' to set the output port and resubmit. + * to 'ofpacts' to set the output port and resubmit. * - * - For logical patch ports, add actions to 'remote_ofpacts_p' + * - For logical patch ports, add actions to 'remote_ofpacts' * instead. (If we put them in 'ofpacts', then the output * would happen on every hypervisor in the multicast group, * effectively duplicating the packet.) */ - ofpbuf_clear(ofpacts_p); - ofpbuf_clear(remote_ofpacts_p); + struct ofpbuf ofpacts; + ofpbuf_init(&ofpacts, 0); + struct ofpbuf remote_ofpacts; + ofpbuf_init(&remote_ofpacts, 0); for (size_t i = 0; i < mc->n_ports; i++) { struct sbrec_port_binding *port = mc->ports[i]; @@ -781,20 +783,20 @@ consider_mc_group(enum mf_field_id mff_ovn_geneve, int zone_id = simap_get(ct_zones, port->logical_port); if (zone_id) { - put_load(zone_id, MFF_LOG_CT_ZONE, 0, 32, ofpacts_p); + put_load(zone_id, MFF_LOG_CT_ZONE, 0, 32, &ofpacts); } if (!strcmp(port->type, "patch")) { put_load(port->tunnel_key, MFF_LOG_OUTPORT, 0, 32, - remote_ofpacts_p); - put_resubmit(OFTABLE_CHECK_LOOPBACK, remote_ofpacts_p); + &remote_ofpacts); + put_resubmit(OFTABLE_CHECK_LOOPBACK, &remote_ofpacts); } else if (simap_contains(&localvif_to_ofport, (port->parent_port && *port->parent_port) ? port->parent_port : port->logical_port) || (!strcmp(port->type, "l3gateway") && port->chassis == chassis)) { - put_load(port->tunnel_key, MFF_LOG_OUTPORT, 0, 32, ofpacts_p); - put_resubmit(OFTABLE_CHECK_LOOPBACK, ofpacts_p); + put_load(port->tunnel_key, MFF_LOG_OUTPORT, 0, 32, &ofpacts); + put_resubmit(OFTABLE_CHECK_LOOPBACK, &ofpacts); } else if (port->chassis && !get_localnet_port(local_datapaths, mc->datapath->tunnel_key)) { /* Add remote chassis only when localnet port not exist, @@ -809,14 +811,14 @@ consider_mc_group(enum mf_field_id mff_ovn_geneve, * * Handle output to the local logical ports in the multicast group, if * any. */ - bool local_ports = ofpacts_p->size > 0; + bool local_ports = ofpacts.size > 0; if (local_ports) { /* Following delivery to local logical ports, restore the multicast * group as the logical output port. */ - put_load(mc->tunnel_key, MFF_LOG_OUTPORT, 0, 32, ofpacts_p); + put_load(mc->tunnel_key, MFF_LOG_OUTPORT, 0, 32, &ofpacts); ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 100, 0, - &match, ofpacts_p, hc_uuid); + &match, &ofpacts, &mc->header_.uuid); } /* Table 32, priority 100. @@ -824,12 +826,12 @@ consider_mc_group(enum mf_field_id mff_ovn_geneve, * * Handle output to the remote chassis in the multicast group, if * any. */ - if (!sset_is_empty(&remote_chassis) || remote_ofpacts_p->size > 0) { - if (remote_ofpacts_p->size > 0) { + if (!sset_is_empty(&remote_chassis) || remote_ofpacts.size > 0) { + if (remote_ofpacts.size > 0) { /* Following delivery to logical patch ports, restore the * multicast group as the logical output port. */ put_load(mc->tunnel_key, MFF_LOG_OUTPORT, 0, 32, - remote_ofpacts_p); + &remote_ofpacts); } const char *chassis_name; @@ -843,20 +845,22 @@ consider_mc_group(enum mf_field_id mff_ovn_geneve, if (!prev || tun->type != prev->type) { put_encapsulation(mff_ovn_geneve, tun, mc->datapath, - mc->tunnel_key, remote_ofpacts_p); + mc->tunnel_key, &remote_ofpacts); prev = tun; } - ofpact_put_OUTPUT(remote_ofpacts_p)->port = tun->ofport; + ofpact_put_OUTPUT(&remote_ofpacts)->port = tun->ofport; } - if (remote_ofpacts_p->size) { + if (remote_ofpacts.size) { if (local_ports) { - put_resubmit(OFTABLE_LOCAL_OUTPUT, remote_ofpacts_p); + put_resubmit(OFTABLE_LOCAL_OUTPUT, &remote_ofpacts); } ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 100, 0, - &match, remote_ofpacts_p, hc_uuid); + &match, &remote_ofpacts, &mc->header_.uuid); } } + ofpbuf_uninit(&ofpacts); + ofpbuf_uninit(&remote_ofpacts); sset_destroy(&remote_chassis); } @@ -871,6 +875,38 @@ update_ofports(struct simap *old, struct simap *new) return changed; } +void physical_handle_port_binding_changes( + struct ovsdb_idl_index *sbrec_chassis_by_name, + struct ovsdb_idl_index *sbrec_port_binding_by_name, + const struct sbrec_port_binding_table *pb_table, + enum mf_field_id mff_ovn_geneve, + const struct sbrec_chassis *chassis, + const struct simap *ct_zones, + struct hmap *local_datapaths, + struct sset *active_tunnels, + struct ovn_desired_flow_table *flow_table) +{ + const struct sbrec_port_binding *binding; + struct ofpbuf ofpacts; + ofpbuf_init(&ofpacts, 0); + SBREC_PORT_BINDING_TABLE_FOR_EACH_TRACKED (binding, pb_table) { + if (sbrec_port_binding_is_deleted(binding)) { + ofctrl_remove_flows(flow_table, &binding->header_.uuid); + } else { + if (!sbrec_port_binding_is_new(binding)) { + ofctrl_remove_flows(flow_table, &binding->header_.uuid); + } + consider_port_binding(sbrec_chassis_by_name, + sbrec_port_binding_by_name, + mff_ovn_geneve, ct_zones, + active_tunnels, local_datapaths, + binding, chassis, + flow_table, &ofpacts); + } + } + +} + void physical_run(struct ovsdb_idl_index *sbrec_chassis_by_name, struct ovsdb_idl_index *sbrec_port_binding_by_name, @@ -1011,22 +1047,18 @@ physical_run(struct ovsdb_idl_index *sbrec_chassis_by_name, consider_port_binding(sbrec_chassis_by_name, sbrec_port_binding_by_name, mff_ovn_geneve, ct_zones, - active_tunnels, - local_datapaths, binding, chassis, + active_tunnels, local_datapaths, + binding, chassis, flow_table, &ofpacts); } /* Handle output to multicast groups, in tables 32 and 33. */ const struct sbrec_multicast_group *mc; - struct ofpbuf remote_ofpacts; - ofpbuf_init(&remote_ofpacts, 0); SBREC_MULTICAST_GROUP_TABLE_FOR_EACH (mc, multicast_group_table) { - consider_mc_group(mff_ovn_geneve, ct_zones, local_datapaths, chassis, - mc, &ofpacts, &remote_ofpacts, flow_table); + consider_mc_group(mff_ovn_geneve, ct_zones, local_datapaths, + chassis, mc, flow_table); } - ofpbuf_uninit(&remote_ofpacts); - /* Table 0, priority 100. * ====================== * diff --git a/ovn/controller/physical.h b/ovn/controller/physical.h index 1dd2b9d..a9c8445 100644 --- a/ovn/controller/physical.h +++ b/ovn/controller/physical.h @@ -55,5 +55,15 @@ void physical_run(struct ovsdb_idl_index *sbrec_chassis_by_name, const struct sset *local_lports, const struct sset *active_tunnels, struct ovn_desired_flow_table *); +void physical_handle_port_binding_changes( + struct ovsdb_idl_index *sbrec_chassis_by_name, + struct ovsdb_idl_index *sbrec_port_binding_by_name, + const struct sbrec_port_binding_table *, + enum mf_field_id mff_ovn_geneve, + const struct sbrec_chassis *, + const struct simap *ct_zones, + struct hmap *local_datapaths, + struct sset *active_tunnels, + struct ovn_desired_flow_table *); #endif /* ovn/physical.h */ From patchwork Mon Aug 13 17:48:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 957081 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ZqZLzgxv"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41q3Hm2QKJz9s78 for ; Tue, 14 Aug 2018 03:53:39 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 3ED54E2F; Mon, 13 Aug 2018 17:48:42 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id A0C5DDD0 for ; Mon, 13 Aug 2018 17:48:38 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f172.google.com (mail-pg1-f172.google.com [209.85.215.172]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 139D77E3 for ; Mon, 13 Aug 2018 17:48:38 +0000 (UTC) Received: by mail-pg1-f172.google.com with SMTP id x5-v6so7852585pgp.7 for ; Mon, 13 Aug 2018 10:48:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=VkHK9Xrko2biwDcQEw05oRvJXZpy9NqJukGbGXHmhoI=; b=ZqZLzgxvTGSRTDeW733SFAxUwnqmbIs14+fKTfPViPjORKnR1qHHlF1WuE7RY7zA/W zl49iydctrEDkNKKUeFj9F9stNrzNvfkWIQvyGTd0KSnntwGwdV+Ck3bMpCOQr2HNTrQ kohG85/TFcPZZQDV+R43/Y8WyzVzEcpUu9ngC3ltkMWoGTeJvHHVeycJ04Sk2uK1fME6 tptp2cNy4GlOKA/arj0Gx/iXQvqU+fUHdj/P641v2RkAm1zbM6FIxKKnpQauQpmBHrGi cbeJzPqfuzX8oW4/Hy3Cz3FDAIytvLYRCIXE1Ngp3LaHpnOUcTbvEL/GeLsJgxiXduz7 VK1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=VkHK9Xrko2biwDcQEw05oRvJXZpy9NqJukGbGXHmhoI=; b=d5FiUMXfsai+sCdwSfVdFXX7knYrdvEcdR1da5r/ZpIHIWQvJSxDx82rAqfdF/ye2S PNHaavsbMTNcWFCqqIXNLcq8w22efiCky21HgEl3c63jE8JsFDkWG8N2vOWJFbaw/HGm XJmP3x0jqHbuZRMNZY4SnxYtcf0JKlMg4V16rf3BPRgn4jLFeic6FmMZfL26AUU2C32+ v1UnU7BB52aTVzcRvHXVG2tNKPJnECi5E2VtYJxhKn3T09XwdDRr/c3nnloSFKSQo6vI CrevSewSs0W2qw4LI3j9CFeXX2L/dm9qzFgB+0WjTKlDN6gxgO24L77b1cQ7YM/wnFW1 uAuA== X-Gm-Message-State: AOUpUlH8lfL1NtPeGfCpcYhxr0brN1pIud79Mk2YdAHwRk5cWnv0fZwm 2p8ChB/wZ+3NqSZUsHQzxvJN2aTd X-Google-Smtp-Source: AA+uWPykzj7MZjCClWSNqhSpnKV5j+Q7rK+Gy9rY074c86l8wTzYWSbNPRtXiZ9K036bX8D7wcgilA== X-Received: by 2002:a62:21cc:: with SMTP id o73-v6mr20077418pfj.21.1534182517445; Mon, 13 Aug 2018 10:48:37 -0700 (PDT) Received: from localhost.localdomain.localdomain ([216.113.160.70]) by smtp.gmail.com with ESMTPSA id d22-v6sm38068664pfk.69.2018.08.13.10.48.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Aug 2018 10:48:36 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Mon, 13 Aug 2018 10:48:10 -0700 Message-Id: <1534182499-75914-12-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> References: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v5 11/20] ovn-controller: incremental processing for multicast group changes X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org This patch handles SB Multicast_Group table changes incrementally. The Multicast_Group table changes can be triggered by creating/deleting a lport of a lswitch. It can be also triggered indirectly by an updating of a port-binding which is referenced by the multicast group. This patch together with previous incremental processing engine related changes supports incremental processing for lflow changes and port-binding changes of lports on other HVs, which are the most common scenarios in a cloud where workloads come up and down. In ovn-scale-test env [1], the total execution time of creating and binding 10k ports on 1k HVs with 40 lswitches and 8 lrouters (5 lswitches/lrouter), decreased from 3h40m to 1h50m because of the less CPU on HVs. The CPU time of ovn-controller for additional 500 lports creating and binding (on top of already existed 10k lports) decreased 90% comparing with master. Latency for end-to-end operations of one extra port on top of the 10k lports, start from port-creation until all flows installation on all related HVs is also improved significantly: before: 20.6s in total - lsp-add: 0.4s - wait-until port up=true: 4.8s - --wait=hv sync: 15.4s after: 7.3s in total - lsp-add: 0.4s - wait-until port up=true: 4.0s - --wait=hv sync: 2.9s [1] https://github.com/openvswitch/ovn-scale-test Signed-off-by: Han Zhou --- lib/ovsdb-idl.c | 4 +++- ovn/controller/ovn-controller.c | 52 ++++++++++++++++++++++++++++++++++++++++- ovn/controller/physical.c | 23 ++++++++++++++++++ ovn/controller/physical.h | 7 ++++++ 4 files changed, 84 insertions(+), 2 deletions(-) diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c index 468b3bf..784ae4e 100644 --- a/lib/ovsdb-idl.c +++ b/lib/ovsdb-idl.c @@ -2308,6 +2308,9 @@ add_tracked_change_for_references(struct ovsdb_idl_row *row) ovsdb_idl_track_is_set(row->table)) { ovs_list_push_back(&row->table->track_list, &row->track_node); + row->change_seqno[OVSDB_IDL_CHANGE_MODIFY] + = row->table->change_seqno[OVSDB_IDL_CHANGE_MODIFY] + = row->table->db->change_seqno + 1; const struct ovsdb_idl_arc *arc; LIST_FOR_EACH (arc, dst_node, &row->dst_arcs) { @@ -2316,7 +2319,6 @@ add_tracked_change_for_references(struct ovsdb_idl_row *row) } } - /* Returns true if a column with mode OVSDB_IDL_MODE_RW changed, false * otherwise. * diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 9fd2cba..4399d6e 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -1180,6 +1180,56 @@ flow_output_sb_port_binding_handler(struct engine_node *node) return true; } +static bool +flow_output_sb_multicast_group_handler(struct engine_node *node) +{ + struct ed_type_runtime_data *data = + (struct ed_type_runtime_data *)engine_get_input( + "runtime_data", node)->data; + struct hmap *local_datapaths = &data->local_datapaths; + struct simap *ct_zones = &data->ct_zones; + + struct ed_type_mff_ovn_geneve *ed_mff_ovn_geneve = + (struct ed_type_mff_ovn_geneve *)engine_get_input( + "mff_ovn_geneve", node)->data; + enum mf_field_id mff_ovn_geneve = ed_mff_ovn_geneve->mff_ovn_geneve; + + struct ovsrec_open_vswitch_table *ovs_table = + (struct ovsrec_open_vswitch_table *)EN_OVSDB_GET( + engine_get_input("OVS_open_vswitch", node)); + struct ovsrec_bridge_table *bridge_table = + (struct ovsrec_bridge_table *)EN_OVSDB_GET( + engine_get_input("OVS_bridge", node)); + const struct ovsrec_bridge *br_int = get_br_int(bridge_table, ovs_table); + const char *chassis_id = get_chassis_id(ovs_table); + + struct ovsdb_idl_index *sbrec_chassis_by_name = + engine_ovsdb_node_get_index( + engine_get_input("SB_chassis", node), + "name"); + const struct sbrec_chassis *chassis = NULL; + if (chassis_id) { + chassis = chassis_lookup_by_name(sbrec_chassis_by_name, chassis_id); + } + ovs_assert(br_int && chassis); + + struct ed_type_flow_output *fo = + (struct ed_type_flow_output *)node->data; + struct ovn_desired_flow_table *flow_table = &fo->flow_table; + + struct sbrec_multicast_group_table *multicast_group_table = + (struct sbrec_multicast_group_table *)EN_OVSDB_GET( + engine_get_input("SB_multicast_group", node)); + + physical_handle_mc_group_changes(multicast_group_table, + mff_ovn_geneve, chassis, ct_zones, local_datapaths, + flow_table); + + node->changed = true; + return true; + +} + struct ovn_controller_exit_args { bool *exiting; bool *restart; @@ -1295,7 +1345,7 @@ main(int argc, char *argv[]) engine_add_input(&en_flow_output, &en_sb_chassis, NULL); engine_add_input(&en_flow_output, &en_sb_encap, NULL); - engine_add_input(&en_flow_output, &en_sb_multicast_group, NULL); + engine_add_input(&en_flow_output, &en_sb_multicast_group, flow_output_sb_multicast_group_handler); engine_add_input(&en_flow_output, &en_sb_datapath_binding, NULL); engine_add_input(&en_flow_output, &en_sb_port_binding, flow_output_sb_port_binding_handler); engine_add_input(&en_flow_output, &en_sb_mac_binding, NULL); diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c index 1cb9f7b..7c22aec 100644 --- a/ovn/controller/physical.c +++ b/ovn/controller/physical.c @@ -908,6 +908,29 @@ void physical_handle_port_binding_changes( } void +physical_handle_mc_group_changes( + const struct sbrec_multicast_group_table *multicast_group_table, + enum mf_field_id mff_ovn_geneve, + const struct sbrec_chassis *chassis, + const struct simap *ct_zones, + const struct hmap *local_datapaths, + struct ovn_desired_flow_table *flow_table) +{ + const struct sbrec_multicast_group *mc; + SBREC_MULTICAST_GROUP_TABLE_FOR_EACH_TRACKED (mc, multicast_group_table) { + if (sbrec_multicast_group_is_deleted(mc)) { + ofctrl_remove_flows(flow_table, &mc->header_.uuid); + } else { + if (!sbrec_multicast_group_is_new(mc)) { + ofctrl_remove_flows(flow_table, &mc->header_.uuid); + } + consider_mc_group(mff_ovn_geneve, ct_zones, local_datapaths, + chassis, mc, flow_table); + } + } +} + +void physical_run(struct ovsdb_idl_index *sbrec_chassis_by_name, struct ovsdb_idl_index *sbrec_port_binding_by_name, const struct sbrec_multicast_group_table *multicast_group_table, diff --git a/ovn/controller/physical.h b/ovn/controller/physical.h index a9c8445..8f18358 100644 --- a/ovn/controller/physical.h +++ b/ovn/controller/physical.h @@ -66,4 +66,11 @@ void physical_handle_port_binding_changes( struct sset *active_tunnels, struct ovn_desired_flow_table *); +void physical_handle_mc_group_changes( + const struct sbrec_multicast_group_table *, + enum mf_field_id mff_ovn_geneve, + const struct sbrec_chassis *, + const struct simap *ct_zones, + const struct hmap *local_datapaths, + struct ovn_desired_flow_table *); #endif /* ovn/physical.h */ From patchwork Mon Aug 13 17:48:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 957082 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="GD8Pe4vH"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41q3JB5XvVz9sBD for ; Tue, 14 Aug 2018 03:54:02 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 17674E25; Mon, 13 Aug 2018 17:48:43 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 2A0CDD9B for ; Mon, 13 Aug 2018 17:48:39 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f194.google.com (mail-pg1-f194.google.com [209.85.215.194]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id BC79E7E3 for ; Mon, 13 Aug 2018 17:48:38 +0000 (UTC) Received: by mail-pg1-f194.google.com with SMTP id a14-v6so7841045pgv.10 for ; Mon, 13 Aug 2018 10:48:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=KylcsdDytDb+M4dk9X6dA1BtinubSu53yBAchDIEqWc=; b=GD8Pe4vH1tU19fnRSyILcYDWPraeaK5zbG0MBliSRFrHg8FOQvuBVMIOU5TfZu6hRv pgJXbL3lm4KrJ1OvWPbEyLtHnkWqWVQfPnd2TLJYLgQFStN0Gklt3J6xcnuuGfjk4Ff6 oMM1P06FcsAXLJT1jQ1Vqfpl9fK0F0127uPZcsWV2q5i+L0p5zWpQw42bUF/hUH1I+w+ TwgnW15P/1g1e7SAHm46xG4ytrCVgo9Ypqwt14Y/97NKrsEzJmZLdVC2XhLwvyiQPqT9 fnxwzApJ3Tgl9Feu9mSoJNLYXXEOkbDmUVmWdpCrB5+Lyi1JKV8s3WppwzbVzupAHjJE 2ZsA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=KylcsdDytDb+M4dk9X6dA1BtinubSu53yBAchDIEqWc=; b=YIy7jQ50wkssd7lzYBTC2H3o9KSIxn15iMi8bK5jichzbdgcvJCI5+XvVJgaiuW53V cjAkwIDhPNAPTAI8JFOpBwQcVteVxhICPx0+6RNaKtNudp77mdahhyfKbuugz5hvD+mI WkGx2sB1Y5zcbw8YfxI30TOLLhTBol15UPPTf9mkTK8YgYC/k7jslchKHev2rOsl+yT5 NBLnw6cwJtfMWS8inxxabro88PudyyblywluWB1QM5nwx6gyWT3Df+bguYi4zd347pBc R9bzRpvCko8Vl4K5vLiwQEN1MVPmj+dI+HbvWuIV1JGPfN5G6wZsXc2V9jJ7IFf2iOA7 EUOA== X-Gm-Message-State: AOUpUlFXceKuIX0vrsaW2Z6+z94YNbuwU4l5sSVmW2CiZYEjlL9ya/IJ jMfTCPcYyBlgFunGHc1ElN8R/1rc X-Google-Smtp-Source: AA+uWPxF7FHlNv1cXkXqtD3fUx25QEHKpOFLD3mgsWLc0UZfH+HWqctz6whv9UA99wUYNP9elF1fTQ== X-Received: by 2002:a63:f18:: with SMTP id e24-v6mr18080895pgl.320.1534182518186; Mon, 13 Aug 2018 10:48:38 -0700 (PDT) Received: from localhost.localdomain.localdomain ([216.113.160.70]) by smtp.gmail.com with ESMTPSA id d22-v6sm38068664pfk.69.2018.08.13.10.48.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Aug 2018 10:48:37 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Mon, 13 Aug 2018 10:48:11 -0700 Message-Id: <1534182499-75914-13-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> References: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v5 12/20] ovsdb-idl: Tracking - preserve data for deleted rows. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org OVSDB IDL can track changes, but for deleted rows, the data is destroyed and only uuid is tracked. In some cases we need to check the data of the deleted rows. This patch preserves data for deleted rows until track clear is called. Signed-off-by: Han Zhou --- lib/ovsdb-idl-provider.h | 2 ++ lib/ovsdb-idl.c | 36 +++++++++++++++++++++++++++++------- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/lib/ovsdb-idl-provider.h b/lib/ovsdb-idl-provider.h index 2eee4fd..30d1d08 100644 --- a/lib/ovsdb-idl-provider.h +++ b/lib/ovsdb-idl-provider.h @@ -73,6 +73,7 @@ struct ovsdb_idl_row { struct ovs_list dst_arcs; /* Backward arcs (ovsdb_idl_arc.dst_node). */ struct ovsdb_idl_table *table; /* Containing table. */ struct ovsdb_datum *old_datum; /* Committed data (null if orphaned). */ + bool parsed; /* Whether the row is parsed. */ /* Transactional data. */ struct ovsdb_datum *new_datum; /* Modified data (null to delete row). */ @@ -88,6 +89,7 @@ struct ovsdb_idl_row { unsigned int change_seqno[OVSDB_IDL_CHANGE_MAX]; struct ovs_list track_node; /* Rows modified/added/deleted by IDL */ unsigned long int *updated; /* Bitmap of columns updated by IDL */ + struct ovsdb_datum *tracked_old_datum; /* Old deleted data. */ }; struct ovsdb_idl_column { diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c index 784ae4e..72799b7 100644 --- a/lib/ovsdb-idl.c +++ b/lib/ovsdb-idl.c @@ -1721,7 +1721,16 @@ ovsdb_idl_db_track_clear(struct ovsdb_idl_db *db) } ovs_list_remove(&row->track_node); ovs_list_init(&row->track_node); - if (ovsdb_idl_row_is_orphan(row)) { + if (ovsdb_idl_row_is_orphan(row) && row->tracked_old_datum) { + ovsdb_idl_row_unparse(row); + const struct ovsdb_idl_table_class *class = + row->table->class_; + for (size_t c = 0; c < class->n_columns; c++) { + ovsdb_datum_destroy(&row->tracked_old_datum[c], + &class->columns[c].type); + } + free(row->tracked_old_datum); + row->tracked_old_datum = NULL; free(row); } } @@ -2464,10 +2473,14 @@ ovsdb_idl_row_parse(struct ovsdb_idl_row *row) const struct ovsdb_idl_table_class *class = row->table->class_; size_t i; + if (row->parsed) { + ovsdb_idl_row_unparse(row); + } for (i = 0; i < class->n_columns; i++) { const struct ovsdb_idl_column *c = &class->columns[i]; (c->parse)(row, &row->old_datum[i]); } + row->parsed = true; } static void @@ -2476,10 +2489,14 @@ ovsdb_idl_row_unparse(struct ovsdb_idl_row *row) const struct ovsdb_idl_table_class *class = row->table->class_; size_t i; + if (!row->parsed) { + return; + } for (i = 0; i < class->n_columns; i++) { const struct ovsdb_idl_column *c = &class->columns[i]; (c->unparse)(row); } + row->parsed = false; } /* The OVSDB-IDL Compound Indexes feature allows for the creation of custom @@ -2807,13 +2824,18 @@ ovsdb_idl_row_clear_old(struct ovsdb_idl_row *row) { ovs_assert(row->old_datum == row->new_datum); if (!ovsdb_idl_row_is_orphan(row)) { - const struct ovsdb_idl_table_class *class = row->table->class_; - size_t i; + if (ovsdb_idl_track_is_set(row->table)) { + row->tracked_old_datum = row->old_datum; + } else { + const struct ovsdb_idl_table_class *class = row->table->class_; + size_t i; - for (i = 0; i < class->n_columns; i++) { - ovsdb_datum_destroy(&row->old_datum[i], &class->columns[i].type); + for (i = 0; i < class->n_columns; i++) { + ovsdb_datum_destroy(&row->old_datum[i], + &class->columns[i].type); + } + free(row->old_datum); } - free(row->old_datum); row->old_datum = row->new_datum = NULL; } } @@ -2986,6 +3008,7 @@ ovsdb_idl_row_destroy_postprocess(struct ovsdb_idl_db *db) LIST_FOR_EACH_SAFE(row, next, track_node, &table->track_list) { if (!ovsdb_idl_track_is_set(row->table)) { ovs_list_remove(&row->track_node); + ovsdb_idl_row_unparse(row); free(row); } } @@ -3016,7 +3039,6 @@ static void ovsdb_idl_delete_row(struct ovsdb_idl_row *row) { ovsdb_idl_remove_from_indexes(row); - ovsdb_idl_row_unparse(row); ovsdb_idl_row_clear_arcs(row, true); ovsdb_idl_row_clear_old(row); if (ovs_list_is_empty(&row->dst_arcs)) { From patchwork Mon Aug 13 17:48:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 957083 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Prq7JGqE"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41q3Jb3LFyz9sBZ for ; Tue, 14 Aug 2018 03:54:23 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id E023DE38; Mon, 13 Aug 2018 17:48:43 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 0FEB5DA3 for ; Mon, 13 Aug 2018 17:48:40 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pf1-f195.google.com (mail-pf1-f195.google.com [209.85.210.195]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 7F7857E3 for ; Mon, 13 Aug 2018 17:48:39 +0000 (UTC) Received: by mail-pf1-f195.google.com with SMTP id k19-v6so8011946pfi.1 for ; Mon, 13 Aug 2018 10:48:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=O68lxZ6WPZuM7aVIqfU8N5oBz2INdPw+PpdV0KSLaJ0=; b=Prq7JGqEBPPo1uGBfXgZDfOQ6GgPDh6OAClWpYzG/xCotcIWFvP44MAmDPfKc8hl2A 776fPN2wlJUWMADODleleiyNEedkSoXyWintAbWZvNOBQE6/O4z8514k0qkT21Q400iw 1MPmgSuv9Kz5JPmWLMutculm00Fc/KTsx7attLfS6FqKyfNiCMj6OJfQ3sjGbdeEaDI7 exHiPcOMFiL+bwoFV/jEZpuSa8CphvmHj3MllOmnARVrxPbebzN8wV5nDHi2/8jVekbI shK7ehp/5pBnN7lDTJqm1lm+4lURYMaNgaa7XYynMtwY/WhZI4+zWFl5gmOfB2B2LxSy w1PQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=O68lxZ6WPZuM7aVIqfU8N5oBz2INdPw+PpdV0KSLaJ0=; b=Ua7SDTQVrzBWTIl6ufN4epbqvlymUDFwWFYm0YtoedjNMfFEyigP/fFtwd+mnGJLrR 4LOvJWZUK8ER0LdsNmVBq7IVm0gx/zWhHnKYRgA4ghW4YtrpDvom3EvN/un5OOrX/agx sg/lRInGd3adwmcjmR8PYZLAhuF0t02o8151TAjEPNI1PycyZ+K9zhtPgB0a8SXrHAvn U88wY0+x1Kid952wW3SCHU8H5zEFcPO5ds6iFCldNhfkEq4RufD1XGcqI1C32FoX4XH8 sRPhA51yIb1l30ChEKIYNogjvtRbjQmtV1O+iCvsGKeaszB6Xav020FBCDaz1NKw+hIq q8Ug== X-Gm-Message-State: AOUpUlFDWsTuVzwNeIJRwfIo1D3qBLKtJXS9NCcXy6fRWohgIAITscjf AZJrdTNC26HffcWMHJyYMld2K2ky X-Google-Smtp-Source: AA+uWPyYzGkAU8gadUQv5oz0df6GDDgcY6whkqlA6MoigmkOnuGtEcv1aHiFHzmXXy0UwndXuLRd8w== X-Received: by 2002:a63:67c3:: with SMTP id b186-v6mr18138678pgc.5.1534182518897; Mon, 13 Aug 2018 10:48:38 -0700 (PDT) Received: from localhost.localdomain.localdomain ([216.113.160.70]) by smtp.gmail.com with ESMTPSA id d22-v6sm38068664pfk.69.2018.08.13.10.48.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Aug 2018 10:48:38 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Mon, 13 Aug 2018 10:48:12 -0700 Message-Id: <1534182499-75914-14-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> References: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v5 13/20] ovn-controller: Split addr_sets from runtime_data. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org Signed-off-by: Han Zhou --- ovn/controller/ovn-controller.c | 75 ++++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 15 deletions(-) diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 4399d6e..a50d134 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -604,6 +604,52 @@ const char *ovs_engine_node_names[] = { OVS_NODES #undef OVS_NODE +struct ed_type_addr_sets { + struct shash addr_sets; + struct sset new; + struct sset deleted; + struct sset updated; +}; + +static void +en_addr_sets_init(struct engine_node *node) +{ + struct ed_type_addr_sets *as = (struct ed_type_addr_sets *)node->data; + shash_init(&as->addr_sets); + sset_init(&as->new); + sset_init(&as->deleted); + sset_init(&as->updated); +} + +static void +en_addr_sets_cleanup(struct engine_node *node) +{ + struct ed_type_addr_sets *as = (struct ed_type_addr_sets *)node->data; + expr_const_sets_destroy(&as->addr_sets); + shash_destroy(&as->addr_sets); + sset_destroy(&as->new); + sset_destroy(&as->deleted); + sset_destroy(&as->updated); +} + +static void +en_addr_sets_run(struct engine_node *node) +{ + struct ed_type_addr_sets *as = (struct ed_type_addr_sets *)node->data; + + sset_clear(&as->new); + sset_clear(&as->deleted); + sset_clear(&as->updated); + expr_const_sets_destroy(&as->addr_sets); + + struct sbrec_address_set_table *as_table = + (struct sbrec_address_set_table *)EN_OVSDB_GET( + engine_get_input("SB_address_set", node)); + + addr_sets_init(as_table, &as->addr_sets); + + node->changed = true; +} struct ed_type_runtime_data { /* Contains "struct local_datapath" nodes. */ @@ -620,7 +666,6 @@ struct ed_type_runtime_data { * _ */ struct sset local_lport_ids; struct sset active_tunnels; - struct shash addr_sets; struct shash port_groups; /* connection tracking zones. */ @@ -644,7 +689,6 @@ en_runtime_data_init(struct engine_node *node) sset_init(&data->local_lports); sset_init(&data->local_lport_ids); sset_init(&data->active_tunnels); - shash_init(&data->addr_sets); shash_init(&data->port_groups); shash_init(&data->pending_ct_zones); simap_init(&data->ct_zones); @@ -662,8 +706,6 @@ en_runtime_data_cleanup(struct engine_node *node) struct ed_type_runtime_data *data = (struct ed_type_runtime_data *)node->data; - expr_const_sets_destroy(&data->addr_sets); - shash_destroy(&data->addr_sets); expr_const_sets_destroy(&data->port_groups); shash_destroy(&data->port_groups); @@ -692,7 +734,6 @@ en_runtime_data_run(struct engine_node *node) struct sset *local_lports = &data->local_lports; struct sset *local_lport_ids = &data->local_lport_ids; struct sset *active_tunnels = &data->active_tunnels; - struct shash *addr_sets = &data->addr_sets; struct shash *port_groups = &data->port_groups; unsigned long *ct_zone_bitmap = data->ct_zone_bitmap; struct shash *pending_ct_zones = &data->pending_ct_zones; @@ -713,7 +754,6 @@ en_runtime_data_run(struct engine_node *node) sset_destroy(local_lports); sset_destroy(local_lport_ids); sset_destroy(active_tunnels); - expr_const_sets_destroy(addr_sets); expr_const_sets_destroy(port_groups); sset_init(local_lports); sset_init(local_lport_ids); @@ -780,11 +820,6 @@ en_runtime_data_run(struct engine_node *node) active_tunnels, local_datapaths, local_lports, local_lport_ids); - struct sbrec_address_set_table *as_table = - (struct sbrec_address_set_table *)EN_OVSDB_GET( - engine_get_input("SB_address_set", node)); - addr_sets_init(as_table, addr_sets); - struct sbrec_port_group_table *pg_table = (struct sbrec_port_group_table *)EN_OVSDB_GET( engine_get_input("SB_port_group", node)); @@ -909,7 +944,6 @@ en_flow_output_run(struct engine_node *node) struct sset *local_lports = &rt_data->local_lports; struct sset *local_lport_ids = &rt_data->local_lport_ids; struct sset *active_tunnels = &rt_data->active_tunnels; - struct shash *addr_sets = &rt_data->addr_sets; struct shash *port_groups = &rt_data->port_groups; struct simap *ct_zones = &rt_data->ct_zones; @@ -931,6 +965,10 @@ en_flow_output_run(struct engine_node *node) engine_ovsdb_node_get_index( engine_get_input("SB_chassis", node), "name"); + struct ed_type_addr_sets *as_data = + (struct ed_type_addr_sets *)engine_get_input("addr_sets", node)->data; + struct shash *addr_sets = &as_data->addr_sets; + const struct sbrec_chassis *chassis = NULL; if (chassis_id) { chassis = chassis_lookup_by_name(sbrec_chassis_by_name, chassis_id); @@ -1022,8 +1060,10 @@ flow_output_sb_logical_flow_handler(struct engine_node *node) struct hmap *local_datapaths = &data->local_datapaths; struct sset *local_lport_ids = &data->local_lport_ids; struct sset *active_tunnels = &data->active_tunnels; - struct shash *addr_sets = &data->addr_sets; struct shash *port_groups = &data->port_groups; + struct ed_type_addr_sets *as_data = + (struct ed_type_addr_sets *)engine_get_input("addr_sets", node)->data; + struct shash *addr_sets = &as_data->addr_sets; struct ovsrec_open_vswitch_table *ovs_table = (struct ovsrec_open_vswitch_table *)EN_OVSDB_GET( @@ -1314,10 +1354,12 @@ main(int argc, char *argv[]) struct ed_type_runtime_data ed_runtime_data; struct ed_type_mff_ovn_geneve ed_mff_ovn_geneve; struct ed_type_flow_output ed_flow_output; + struct ed_type_addr_sets ed_addr_sets; ENGINE_NODE(runtime_data, "runtime_data"); ENGINE_NODE(mff_ovn_geneve, "mff_ovn_geneve"); ENGINE_NODE(flow_output, "flow_output"); + ENGINE_NODE(addr_sets, "addr_sets"); #define SB_NODE(NAME, NAME_STR) ENGINE_NODE_SB(NAME, NAME_STR); SB_NODES @@ -1335,6 +1377,10 @@ main(int argc, char *argv[]) engine_ovsdb_node_add_index(&en_sb_datapath_binding, "key", sbrec_datapath_binding_by_key); /* Add dependencies between inc-proc-engine nodes. */ + + engine_add_input(&en_addr_sets, &en_sb_address_set, NULL); + + engine_add_input(&en_flow_output, &en_addr_sets, NULL); engine_add_input(&en_flow_output, &en_runtime_data, NULL); engine_add_input(&en_flow_output, &en_mff_ovn_geneve, NULL); @@ -1362,7 +1408,6 @@ main(int argc, char *argv[]) engine_add_input(&en_runtime_data, &en_ovs_interface, NULL); engine_add_input(&en_runtime_data, &en_sb_chassis, NULL); - engine_add_input(&en_runtime_data, &en_sb_address_set, NULL); engine_add_input(&en_runtime_data, &en_sb_port_group, NULL); engine_add_input(&en_runtime_data, &en_sb_datapath_binding, NULL); engine_add_input(&en_runtime_data, &en_sb_port_binding, runtime_data_sb_port_binding_handler); @@ -1531,7 +1576,7 @@ main(int argc, char *argv[]) if (br_int && chassis) { char *error = ofctrl_inject_pkt(br_int, pending_pkt.flow_s, &ed_runtime_data.port_groups, - &ed_runtime_data.addr_sets); + &ed_addr_sets.addr_sets); if (error) { unixctl_command_reply_error(pending_pkt.conn, error); free(error); From patchwork Mon Aug 13 17:48:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 957085 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="qe4whRdb"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41q3Kl2xjjz9sBZ for ; Tue, 14 Aug 2018 03:55:23 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id D8333E30; Mon, 13 Aug 2018 17:48:45 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id B302ADBC for ; Mon, 13 Aug 2018 17:48:41 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f174.google.com (mail-pg1-f174.google.com [209.85.215.174]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 6D7987E3 for ; Mon, 13 Aug 2018 17:48:40 +0000 (UTC) Received: by mail-pg1-f174.google.com with SMTP id a14-v6so7841074pgv.10 for ; Mon, 13 Aug 2018 10:48:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=VbzpzVTSC7UacOh2sinXeFC+1BI77U2K97nBAups1wk=; b=qe4whRdbFLLnu+CMgxNHRH4JZ8H1+DtomIIbnSTZhG619au++xB5UGHSz94WGEnf7M QxAhL3KZCPwt8l5oK34RS6RSv45/hFOakfPI5yfmSNi1e7q9nZZHV8G6cJSSyIQ4cyYH 4Zv6AfxORNz6hqSs4thKmxm4pUwfIolGkcYrv6xPlGdOP1Y4o89lGHaM3zGgJPhM/IzW ZMHUFYoSr2GsiDVX6BHKlw/HZj93droYvngtxw/NyqR4WmVi6JkBb6oAUXlWxNmfeA+R mF1iITyCmapfvQHRvbCKoovJGJKGqQNQWkNDCnpM/R9wdmKwkhmcY5eaC8mTQvBahOLX XpQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=VbzpzVTSC7UacOh2sinXeFC+1BI77U2K97nBAups1wk=; b=p0IMpFxEo3WNRkvUM6yJomIUJBOdKaILTnew5Gs+i/yFuXIU0hkj3OGwJEjvlSGSAa OVkTTSPIHMfFeaNT4sRE/iEwahsny0KbA+HrjYTE375pcLA/8izy5kv+pG3t3VO30x4Z fDmjC4Rc1LHrSZGt4t/vm4Aq3TXBxDzQOUzyl4BsioJ1KAyFdqEEXKqNfvQ8LxNJgpLK MFbbzD6RKf2oqt4VUCi2J1fpcbVlqXIksILJ/TE+n7Jh44sdvjzCBpYBg30ADsZbwxio Yz9uDN25PgQztgbs5CBLBMux1MnU5uu/av8Gl2HzGre6hU03Pa2z2QhvlWuVKda0yLSt Z10w== X-Gm-Message-State: AOUpUlEweS5KNOsogLsXFlx4CU9IUPbgM2cxaBKHDsGknpwJkc8LwRex wWWebbCIt60iHgwYceAPpu7xPEdq X-Google-Smtp-Source: AA+uWPzrIWIp+mWdqJkBcBoERAMyMi8Epp/CdnbjDKeRnpfwp1LSF1/UTWkfcK66hn0g56CFx4gu/g== X-Received: by 2002:a62:2bc8:: with SMTP id r191-v6mr19790408pfr.164.1534182519645; Mon, 13 Aug 2018 10:48:39 -0700 (PDT) Received: from localhost.localdomain.localdomain ([216.113.160.70]) by smtp.gmail.com with ESMTPSA id d22-v6sm38068664pfk.69.2018.08.13.10.48.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Aug 2018 10:48:39 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Mon, 13 Aug 2018 10:48:13 -0700 Message-Id: <1534182499-75914-15-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> References: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v5 14/20] ovn-controller: Maintain resource references for logical flows. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org This patch maintains the cross reference between logical flows and the resources such as address sets and port groups that are used by logical flows. This data will be needed in address set and port group incremental processing. Signed-off-by: Han Zhou --- include/ovn/expr.h | 5 +- ovn/controller/lflow.c | 147 ++++++++++++++++++++++++++++++++++++++-- ovn/controller/lflow.h | 52 ++++++++++++++ ovn/controller/ovn-controller.c | 13 +++- ovn/lib/actions.c | 2 +- ovn/lib/expr.c | 21 ++++-- ovn/utilities/ovn-trace.c | 2 +- tests/test-ovn.c | 7 +- 8 files changed, 231 insertions(+), 18 deletions(-) diff --git a/include/ovn/expr.h b/include/ovn/expr.h index 3995e62..c0664ac 100644 --- a/include/ovn/expr.h +++ b/include/ovn/expr.h @@ -65,6 +65,7 @@ struct flow; struct ofpbuf; struct shash; struct simap; +struct sset; /* "Measurement level" of a field. See "Level of Measurement" in the large * comment on struct expr_symbol below for more information. */ @@ -383,10 +384,12 @@ void expr_format(const struct expr *, struct ds *); void expr_print(const struct expr *); struct expr *expr_parse(struct lexer *, const struct shash *symtab, const struct shash *addr_sets, - const struct shash *port_groups); + const struct shash *port_groups, + struct sset *addr_sets_ref); struct expr *expr_parse_string(const char *, const struct shash *symtab, const struct shash *addr_sets, const struct shash *port_groups, + struct sset *addr_sets_ref, char **errorp); struct expr *expr_clone(struct expr *); diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c index f7cb6d4..e13ee69 100644 --- a/ovn/controller/lflow.c +++ b/ovn/controller/lflow.c @@ -79,6 +79,7 @@ static bool consider_logical_flow( struct ovn_desired_flow_table *, struct ovn_extend_table *group_table, struct ovn_extend_table *meter_table, + struct lflow_resource_ref *lfrr, uint32_t *conj_id_ofs); static bool @@ -138,6 +139,128 @@ is_switch(const struct sbrec_datapath_binding *ldp) } +void +lflow_resource_init(struct lflow_resource_ref *lfrr) +{ + hmap_init(&lfrr->ref_lflow_table); + hmap_init(&lfrr->lflow_ref_table); +} + +void +lflow_resource_destroy(struct lflow_resource_ref *lfrr) +{ + struct ref_lflow_node *rlfn, *rlfn_next; + HMAP_FOR_EACH_SAFE (rlfn, rlfn_next, node, &lfrr->ref_lflow_table) { + free(rlfn->ref_name); + struct lflow_ref_list_node *lrln, *next; + LIST_FOR_EACH_SAFE (lrln, next, ref_list, &rlfn->ref_lflow_head) { + ovs_list_remove(&lrln->ref_list); + ovs_list_remove(&lrln->lflow_list); + free(lrln); + } + hmap_remove(&lfrr->ref_lflow_table, &rlfn->node); + free(rlfn); + } + hmap_destroy(&lfrr->ref_lflow_table); + + struct lflow_ref_node *lfrn, *lfrn_next; + HMAP_FOR_EACH_SAFE (lfrn, lfrn_next, node, &lfrr->lflow_ref_table) { + hmap_remove(&lfrr->lflow_ref_table, &lfrn->node); + free(lfrn); + } + hmap_destroy(&lfrr->lflow_ref_table); +} + +void +lflow_resource_clear(struct lflow_resource_ref *lfrr) +{ + lflow_resource_destroy(lfrr); + lflow_resource_init(lfrr); +} + +static struct ref_lflow_node* +ref_lflow_lookup(struct hmap *ref_lflow_table, + enum ref_type type, const char *ref_name) +{ + struct ref_lflow_node *rlfn; + + HMAP_FOR_EACH_WITH_HASH (rlfn, node, hash_string(ref_name, type), + ref_lflow_table) { + if (rlfn->type == type && !strcmp(rlfn->ref_name, ref_name)) { + return rlfn; + } + } + return NULL; +} + +static struct lflow_ref_node* +lflow_ref_lookup(struct hmap *lflow_ref_table, + const struct uuid *lflow_uuid) +{ + struct lflow_ref_node *lfrn; + + HMAP_FOR_EACH_WITH_HASH (lfrn, node, uuid_hash(lflow_uuid), + lflow_ref_table) { + if (uuid_equals(&lfrn->lflow_uuid, lflow_uuid)) { + return lfrn; + } + } + return NULL; +} + +static void +lflow_resource_add(struct lflow_resource_ref *lfrr, enum ref_type type, + const char *ref_name, const struct uuid *lflow_uuid) +{ + struct ref_lflow_node *rlfn = ref_lflow_lookup(&lfrr->ref_lflow_table, + type, ref_name); + if (!rlfn) { + rlfn = xzalloc(sizeof *rlfn); + rlfn->node.hash = hash_string(ref_name, type); + rlfn->type = type; + rlfn->ref_name = xstrdup(ref_name); + ovs_list_init(&rlfn->ref_lflow_head); + hmap_insert(&lfrr->ref_lflow_table, &rlfn->node, rlfn->node.hash); + } + + struct lflow_ref_node *lfrn = lflow_ref_lookup(&lfrr->lflow_ref_table, + lflow_uuid); + if (!lfrn) { + lfrn = xzalloc(sizeof *lfrn); + lfrn->node.hash = uuid_hash(lflow_uuid); + lfrn->lflow_uuid = *lflow_uuid; + ovs_list_init(&lfrn->lflow_ref_head); + hmap_insert(&lfrr->lflow_ref_table, &lfrn->node, lfrn->node.hash); + } + + struct lflow_ref_list_node *lrln = xzalloc(sizeof *lrln); + lrln->type = type; + lrln->ref_name = xstrdup(ref_name); + lrln->lflow_uuid = *lflow_uuid; + ovs_list_push_back(&rlfn->ref_lflow_head, &lrln->ref_list); + ovs_list_push_back(&lfrn->lflow_ref_head, &lrln->lflow_list); +} + +static void +lflow_resource_destroy_lflow(struct lflow_resource_ref *lfrr, + const struct uuid *lflow_uuid) +{ + struct lflow_ref_node *lfrn = lflow_ref_lookup(&lfrr->lflow_ref_table, + lflow_uuid); + if (!lfrn) { + return; + } + + hmap_remove(&lfrr->lflow_ref_table, &lfrn->node); + struct lflow_ref_list_node *lrln, *next; + LIST_FOR_EACH_SAFE (lrln, next, lflow_list, &lfrn->lflow_ref_head) { + ovs_list_remove(&lrln->ref_list); + ovs_list_remove(&lrln->lflow_list); + free(lrln); + } + free(lfrn); +} + /* Adds the logical flows from the Logical_Flow table to flow tables. */ static void add_logical_flows( @@ -156,6 +279,7 @@ add_logical_flows( struct ovn_desired_flow_table *flow_table, struct ovn_extend_table *group_table, struct ovn_extend_table *meter_table, + struct lflow_resource_ref *lfrr, uint32_t *conj_id_ofs) { const struct sbrec_logical_flow *lflow; @@ -188,7 +312,7 @@ add_logical_flows( &nd_ra_opts, addr_sets, port_groups, active_tunnels, local_lport_ids, flow_table, group_table, meter_table, - conj_id_ofs)) { + lfrr, conj_id_ofs)) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5); VLOG_ERR_RL(&rl, "Conjunction id overflow when processing lflow " UUID_FMT, UUID_ARGS(&lflow->header_.uuid)); @@ -217,6 +341,7 @@ lflow_handle_changed_flows( struct ovn_desired_flow_table *flow_table, struct ovn_extend_table *group_table, struct ovn_extend_table *meter_table, + struct lflow_resource_ref *lfrr, uint32_t *conj_id_ofs) { bool ret = true; @@ -250,6 +375,8 @@ lflow_handle_changed_flows( VLOG_DBG("handle deleted lflow "UUID_FMT, UUID_ARGS(&lflow->header_.uuid)); ofctrl_remove_flows(flow_table, &lflow->header_.uuid); + /* Delete entries from lflow resource reference. */ + lflow_resource_destroy_lflow(lfrr, &lflow->header_.uuid); } } SBREC_LOGICAL_FLOW_TABLE_FOR_EACH_TRACKED (lflow, logical_flow_table) { @@ -261,6 +388,8 @@ lflow_handle_changed_flows( VLOG_DBG("handle updated lflow "UUID_FMT, UUID_ARGS(&lflow->header_.uuid)); ofctrl_remove_flows(flow_table, &lflow->header_.uuid); + /* Delete entries from lflow resource reference. */ + lflow_resource_destroy_lflow(lfrr, &lflow->header_.uuid); } VLOG_DBG("handle new lflow "UUID_FMT, UUID_ARGS(&lflow->header_.uuid)); @@ -272,7 +401,7 @@ lflow_handle_changed_flows( &nd_ra_opts, addr_sets, port_groups, active_tunnels, local_lport_ids, flow_table, group_table, meter_table, - conj_id_ofs)) { + lfrr, conj_id_ofs)) { ret = false; break; } @@ -313,6 +442,7 @@ consider_logical_flow( struct ovn_desired_flow_table *flow_table, struct ovn_extend_table *group_table, struct ovn_extend_table *meter_table, + struct lflow_resource_ref *lfrr, uint32_t *conj_id_ofs) { /* Determine translation of logical table IDs to physical table IDs. */ @@ -372,8 +502,16 @@ consider_logical_flow( struct hmap matches; struct expr *expr; + struct sset addr_sets_ref = SSET_INITIALIZER(&addr_sets_ref); expr = expr_parse_string(lflow->match, &symtab, addr_sets, port_groups, - &error); + &addr_sets_ref, &error); + const char *addr_set_name; + SSET_FOR_EACH (addr_set_name, &addr_sets_ref) { + lflow_resource_add(lfrr, REF_TYPE_ADDRSET, addr_set_name, + &lflow->header_.uuid); + } + sset_destroy(&addr_sets_ref); + if (!error) { if (prereqs) { expr = expr_combine(EXPR_T_AND, expr, prereqs); @@ -589,6 +727,7 @@ lflow_run(struct ovsdb_idl_index *sbrec_chassis_by_name, struct ovn_desired_flow_table *flow_table, struct ovn_extend_table *group_table, struct ovn_extend_table *meter_table, + struct lflow_resource_ref *lfrr, uint32_t *conj_id_ofs) { COVERAGE_INC(lflow_run); @@ -599,7 +738,7 @@ lflow_run(struct ovsdb_idl_index *sbrec_chassis_by_name, dhcpv6_options_table, logical_flow_table, local_datapaths, chassis, addr_sets, port_groups, active_tunnels, local_lport_ids, flow_table, group_table, - meter_table, conj_id_ofs); + meter_table, lfrr, conj_id_ofs); add_neighbor_flows(sbrec_port_binding_by_name, mac_binding_table, flow_table); } diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h index 31e34e2..bb5949b 100644 --- a/ovn/controller/lflow.h +++ b/ovn/controller/lflow.h @@ -34,11 +34,15 @@ */ #include +#include "openvswitch/hmap.h" +#include "openvswitch/uuid.h" +#include "openvswitch/list.h" struct ovn_extend_table; struct ovsdb_idl_index; struct ovn_desired_flow_table; struct hmap; +struct hmap_node; struct sbrec_chassis; struct sbrec_dhcp_options_table; struct sbrec_dhcpv6_options_table; @@ -65,6 +69,52 @@ struct uuid; /* The number of tables for the ingress and egress pipelines. */ #define LOG_PIPELINE_LEN 24 +enum ref_type { + REF_TYPE_ADDRSET +}; + +/* Maintains the relationship for a pair of named resource and + * a lflow, indexed by both ref_lflow_table and lflow_ref_table. */ +struct lflow_ref_list_node { + struct ovs_list lflow_list; /* list for same lflow */ + struct ovs_list ref_list; /* list for same ref */ + enum ref_type type; + char *ref_name; + struct uuid lflow_uuid; +}; + +struct ref_lflow_node { + struct hmap_node node; + enum ref_type type; /* key */ + char *ref_name; /* key */ + struct ovs_list ref_lflow_head; +}; + +struct lflow_ref_node { + struct hmap_node node; + struct uuid lflow_uuid; /* key */ + struct ovs_list lflow_ref_head; +}; + +struct lflow_resource_ref { + /* A map from a referenced resource type & name (e.g. address_set AS1) + * to a list of lflows that are referencing the named resource. Data + * type of each node in this hmap is struct ref_lflow_node. The + * ref_lflow_head in each node points to a list of + * lflow_ref_list_node.ref_list. */ + struct hmap ref_lflow_table; + + /* A map from a lflow uuid to a list of named resources that are + * referenced by the lflow. Data type of each node in this hmap is + * struct lflow_ref_node. The lflow_ref_head in each node points to + * a list of lflow_ref_list_node.lflow_list. */ + struct hmap lflow_ref_table; +}; + +void lflow_resource_init(struct lflow_resource_ref *); +void lflow_resource_destroy(struct lflow_resource_ref *); +void lflow_resource_clear(struct lflow_resource_ref *); + void lflow_init(void); void lflow_run(struct ovsdb_idl_index *sbrec_chassis_by_name, struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath, @@ -82,6 +132,7 @@ void lflow_run(struct ovsdb_idl_index *sbrec_chassis_by_name, struct ovn_desired_flow_table *, struct ovn_extend_table *group_table, struct ovn_extend_table *meter_table, + struct lflow_resource_ref *, uint32_t *conj_id_ofs); bool lflow_handle_changed_flows( @@ -100,6 +151,7 @@ bool lflow_handle_changed_flows( struct ovn_desired_flow_table *, struct ovn_extend_table *group_table, struct ovn_extend_table *meter_table, + struct lflow_resource_ref *, uint32_t *conj_id_ofs); void lflow_destroy(void); diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index a50d134..261c087 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -911,6 +911,8 @@ struct ed_type_flow_output { struct ovn_extend_table meter_table; /* conjunction id offset */ uint32_t conj_id_ofs; + /* lflow resource cross reference */ + struct lflow_resource_ref lflow_resource_ref; }; static void @@ -922,6 +924,7 @@ en_flow_output_init(struct engine_node *node) ovn_extend_table_init(&data->group_table); ovn_extend_table_init(&data->meter_table); data->conj_id_ofs = 1; + lflow_resource_init(&data->lflow_resource_ref); } static void @@ -932,6 +935,7 @@ en_flow_output_cleanup(struct engine_node *node) ovn_desired_flow_table_destroy(&data->flow_table); ovn_extend_table_destroy(&data->group_table); ovn_extend_table_destroy(&data->meter_table); + lflow_resource_destroy(&data->lflow_resource_ref); } static void @@ -982,6 +986,7 @@ en_flow_output_run(struct engine_node *node) struct ovn_extend_table *group_table = &fo->group_table; struct ovn_extend_table *meter_table = &fo->meter_table; uint32_t *conj_id_ofs = &fo->conj_id_ofs; + struct lflow_resource_ref *lfrr = &fo->lflow_resource_ref; static bool first_run = true; if (first_run) { @@ -990,6 +995,7 @@ en_flow_output_run(struct engine_node *node) ovn_desired_flow_table_clear(flow_table); ovn_extend_table_clear(group_table, false /* desired */); ovn_extend_table_clear(meter_table, false /* desired */); + lflow_resource_clear(lfrr); } struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath = @@ -1027,7 +1033,8 @@ en_flow_output_run(struct engine_node *node) mac_binding_table, chassis, local_datapaths, addr_sets, port_groups, active_tunnels, local_lport_ids, - flow_table, group_table, meter_table, conj_id_ofs); + flow_table, group_table, meter_table, lfrr, + conj_id_ofs); struct sbrec_multicast_group_table *multicast_group_table = (struct sbrec_multicast_group_table *)EN_OVSDB_GET( @@ -1091,6 +1098,7 @@ flow_output_sb_logical_flow_handler(struct engine_node *node) struct ovn_extend_table *group_table = &fo->group_table; struct ovn_extend_table *meter_table = &fo->meter_table; uint32_t *conj_id_ofs = &fo->conj_id_ofs; + struct lflow_resource_ref *lfrr = &fo->lflow_resource_ref; struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath = engine_ovsdb_node_get_index( @@ -1121,7 +1129,8 @@ flow_output_sb_logical_flow_handler(struct engine_node *node) logical_flow_table, local_datapaths, chassis, addr_sets, port_groups, active_tunnels, local_lport_ids, - flow_table, group_table, meter_table, conj_id_ofs); + flow_table, group_table, meter_table, lfrr, + conj_id_ofs); node->changed = true; return handled; diff --git a/ovn/lib/actions.c b/ovn/lib/actions.c index 083d1ca..6d7dc5c 100644 --- a/ovn/lib/actions.c +++ b/ovn/lib/actions.c @@ -236,7 +236,7 @@ add_prerequisite(struct action_context *ctx, const char *prerequisite) struct expr *expr; char *error; - expr = expr_parse_string(prerequisite, ctx->pp->symtab, NULL, NULL, + expr = expr_parse_string(prerequisite, ctx->pp->symtab, NULL, NULL, NULL, &error); ovs_assert(!error); ctx->prereqs = expr_combine(EXPR_T_AND, ctx->prereqs, expr); diff --git a/ovn/lib/expr.c b/ovn/lib/expr.c index 148ac86..13c81c8 100644 --- a/ovn/lib/expr.c +++ b/ovn/lib/expr.c @@ -465,6 +465,7 @@ struct expr_context { const struct shash *symtab; /* Symbol table. */ const struct shash *addr_sets; /* Address set table. */ const struct shash *port_groups; /* Port group table. */ + struct sset *addr_sets_ref; /* The set of address set referenced. */ bool not; /* True inside odd number of NOT operators. */ }; @@ -727,6 +728,10 @@ static bool parse_addr_sets(struct expr_context *ctx, struct expr_constant_set *cs, size_t *allocated_values) { + if (ctx->addr_sets_ref) { + sset_add(ctx->addr_sets_ref, ctx->lexer->token.s); + } + struct expr_constant_set *addr_sets = (ctx->addr_sets ? shash_find_data(ctx->addr_sets, ctx->lexer->token.s) @@ -1261,12 +1266,14 @@ expr_parse__(struct expr_context *ctx) struct expr * expr_parse(struct lexer *lexer, const struct shash *symtab, const struct shash *addr_sets, - const struct shash *port_groups) + const struct shash *port_groups, + struct sset *addr_sets_ref) { struct expr_context ctx = { .lexer = lexer, .symtab = symtab, .addr_sets = addr_sets, - .port_groups = port_groups }; + .port_groups = port_groups, + .addr_sets_ref = addr_sets_ref }; return lexer->error ? NULL : expr_parse__(&ctx); } @@ -1280,13 +1287,15 @@ struct expr * expr_parse_string(const char *s, const struct shash *symtab, const struct shash *addr_sets, const struct shash *port_groups, + struct sset *addr_sets_ref, char **errorp) { struct lexer lexer; lexer_init(&lexer, s); lexer_get(&lexer); - struct expr *expr = expr_parse(&lexer, symtab, addr_sets, port_groups); + struct expr *expr = expr_parse(&lexer, symtab, addr_sets, port_groups, + addr_sets_ref); lexer_force_end(&lexer); *errorp = lexer_steal_error(&lexer); if (*errorp) { @@ -1510,7 +1519,7 @@ expr_get_level(const struct expr *expr) static enum expr_level expr_parse_level(const char *s, const struct shash *symtab, char **errorp) { - struct expr *expr = expr_parse_string(s, symtab, NULL, NULL, errorp); + struct expr *expr = expr_parse_string(s, symtab, NULL, NULL, NULL, errorp); enum expr_level level = expr ? expr_get_level(expr) : EXPR_L_NOMINAL; expr_destroy(expr); return level; @@ -1668,7 +1677,7 @@ parse_and_annotate(const char *s, const struct shash *symtab, char *error; struct expr *expr; - expr = expr_parse_string(s, symtab, NULL, NULL, &error); + expr = expr_parse_string(s, symtab, NULL, NULL, NULL, &error); if (expr) { expr = expr_annotate_(expr, symtab, nesting, &error); } @@ -3392,7 +3401,7 @@ expr_parse_microflow(const char *s, const struct shash *symtab, lexer_init(&lexer, s); lexer_get(&lexer); - struct expr *e = expr_parse(&lexer, symtab, addr_sets, port_groups); + struct expr *e = expr_parse(&lexer, symtab, addr_sets, port_groups, NULL); lexer_force_end(&lexer); if (e) { diff --git a/ovn/utilities/ovn-trace.c b/ovn/utilities/ovn-trace.c index 7ca3d97..92a2824 100644 --- a/ovn/utilities/ovn-trace.c +++ b/ovn/utilities/ovn-trace.c @@ -813,7 +813,7 @@ read_flows(void) char *error; struct expr *match; match = expr_parse_string(sblf->match, &symtab, &address_sets, - &port_groups, &error); + &port_groups, NULL, &error); if (error) { VLOG_WARN("%s: parsing expression failed (%s)", sblf->match, error); diff --git a/tests/test-ovn.c b/tests/test-ovn.c index d4a5d59..ce4e8e3 100644 --- a/tests/test-ovn.c +++ b/tests/test-ovn.c @@ -281,7 +281,7 @@ test_parse_expr__(int steps) char *error; expr = expr_parse_string(ds_cstr(&input), &symtab, &addr_sets, - &port_groups, &error); + &port_groups, NULL, &error); if (!error && steps > 0) { expr = expr_annotate(expr, &symtab, &error); } @@ -405,7 +405,8 @@ test_evaluate_expr(struct ovs_cmdl_context *ctx) while (!ds_get_test_line(&input, stdin)) { struct expr *expr; - expr = expr_parse_string(ds_cstr(&input), &symtab, NULL, NULL, &error); + expr = expr_parse_string(ds_cstr(&input), &symtab, NULL, NULL, NULL, + &error); if (!error) { expr = expr_annotate(expr, &symtab, &error); } @@ -880,7 +881,7 @@ test_tree_shape_exhaustively(struct expr *expr, struct shash *symtab, char *error; modified = expr_parse_string(ds_cstr(&s), symtab, NULL, - NULL, &error); + NULL, NULL, &error); if (error) { fprintf(stderr, "%s fails to parse (%s)\n", ds_cstr(&s), error); From patchwork Mon Aug 13 17:48:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 957090 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="iaSvEZhl"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41q3L61BjCz9sBD for ; Tue, 14 Aug 2018 03:55:42 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id A009BE56; Mon, 13 Aug 2018 17:48:46 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 507AF9D7 for ; Mon, 13 Aug 2018 17:48:42 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pf1-f196.google.com (mail-pf1-f196.google.com [209.85.210.196]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 2722C7C4 for ; Mon, 13 Aug 2018 17:48:41 +0000 (UTC) Received: by mail-pf1-f196.google.com with SMTP id j26-v6so7988857pfi.10 for ; Mon, 13 Aug 2018 10:48:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=DexXkTk4nEQOf1RuBOzN23sjvdAf5SBiq8H4nZ+qE3Q=; b=iaSvEZhlOA645FtcSvBD+sGj2r6a4uoImGmbCBk1KYgx2xxgrUJHvhzZ6e6FRvOZQI frlCPBaiRsyNdIy7R46BmzxAW+P1046IDlUvI0fk1lL+wc99ZMW2Y8PG1DUHqtfbyPQl rFAl+J1lf5LN8OkXzbMpYa0S1U8m020n/4Mv7J8B7PTk1UrOjtj0wUVBE9wwgrHfBSmY xM5HgcKTs6G1jScp0RlIVvoJHYn0UkbHUaQZiCFQfhohFcamLmsRde37eDpmJ8lNe7kX hXqdY2Xvyep6xtcJfTWu5jLgLq6gp8Q9VXt7770hrrPH7BGmRRppkxA435coUdpFQlke fdaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=DexXkTk4nEQOf1RuBOzN23sjvdAf5SBiq8H4nZ+qE3Q=; b=Sgf3FURfev3bCSuz1YgLvlKkbKk1cOxGexxrVTYoTdh2GXaP6WVLoBkpsjs+eFjcjA WrURA7p+mONDSYkbRkIZTilZu1JC8F+Xf5Qdi4RctUcoSc2sdOMtcgjbwqvnECjFTFju /W4Ke3Ru9eeb7AuTDWtAYOth0Hcn0c/IB19UuXH/MKAkqLYAA+n3+9b8+Lr7qY8+6joj jXxd/7okrrVtCseT2LcjZVEGaJgDZu3jfXjlLKKklEj6cRZGJFJPDPu2Ic3wEM2NAQMf +PuBPxhZkQdJV7OXHFABN8f1VXFrwQp3xdNNGQ0XRaWNX5mp9B68Kd4zQZXdsMr6lguT 9ilA== X-Gm-Message-State: AOUpUlFCkKGY0p/rGuq0dgVw3su3WOZf+83jhMlsrl/x5Kd2N8090TJ1 nLOACbBz6iYIhh21F6Yh1AXcwgJe X-Google-Smtp-Source: AA+uWPxh9tXDUjnw+lTzXEhg/FJKPbVxAr4vaDAvZ2wHai2WZRwyNbVAVRnEzQM/vGdN7NE0gJP18w== X-Received: by 2002:a63:a745:: with SMTP id w5-v6mr18272444pgo.374.1534182520519; Mon, 13 Aug 2018 10:48:40 -0700 (PDT) Received: from localhost.localdomain.localdomain ([216.113.160.70]) by smtp.gmail.com with ESMTPSA id d22-v6sm38068664pfk.69.2018.08.13.10.48.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Aug 2018 10:48:39 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Mon, 13 Aug 2018 10:48:14 -0700 Message-Id: <1534182499-75914-16-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> References: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v5 15/20] ovn-controller: Incremental processing for address-set changes. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org When the content of an address set changes, ovn-controller will not recompute all flows but only the ones related to the changed address-set. The performance test result is discussed at [1]. [1] https://mail.openvswitch.org/pipermail/ovs-discuss/2018-June/046880.html Tested-by: Mark Michelson Signed-off-by: Han Zhou --- ovn/controller/lflow.c | 107 +++++++++++++++++++++++++ ovn/controller/lflow.h | 22 +++++ ovn/controller/ovn-controller.c | 172 +++++++++++++++++++++++++++++++++++++++- tests/ovn.at | 74 +++++++++++++++++ 4 files changed, 373 insertions(+), 2 deletions(-) diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c index e13ee69..f3d7b44 100644 --- a/ovn/controller/lflow.c +++ b/ovn/controller/lflow.c @@ -413,6 +413,113 @@ lflow_handle_changed_flows( return ret; } +bool +lflow_handle_changed_ref( + enum ref_type ref_type, + const char *ref_name, + struct ovsdb_idl_index *sbrec_chassis_by_name, + struct ovsdb_idl_index *sbrec_multicast_group_by_name_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, + const struct sbrec_logical_flow_table *logical_flow_table, + const struct hmap *local_datapaths, + const struct sbrec_chassis *chassis, + const struct shash *addr_sets, + const struct shash *port_groups, + const struct sset *active_tunnels, + const struct sset *local_lport_ids, + struct ovn_desired_flow_table *flow_table, + struct ovn_extend_table *group_table, + struct ovn_extend_table *meter_table, + struct lflow_resource_ref *lfrr, + uint32_t *conj_id_ofs, + bool *changed) +{ + struct ref_lflow_node *rlfn = ref_lflow_lookup(&lfrr->ref_lflow_table, + ref_type, ref_name); + if (!rlfn) { + *changed = false; + return true; + } + VLOG_DBG("Handle changed lflow reference for resource type: %d," + " name: %s.", ref_type, ref_name); + *changed = false; + bool ret = true; + + hmap_remove(&lfrr->ref_lflow_table, &rlfn->node); + + struct lflow_ref_list_node *lrln, *next; + /* Detach the rlfn->ref_lflow_head nodes from the lfrr table and clean + * up all other nodes related to the lflows that uses the resource, + * so that the old nodes won't interfere with updating the lfrr table + * when reparsing the lflows. */ + LIST_FOR_EACH (lrln, ref_list, &rlfn->ref_lflow_head) { + ovs_list_remove(&lrln->lflow_list); + lflow_resource_destroy_lflow(lfrr, &lrln->lflow_uuid); + } + + struct hmap dhcp_opts = HMAP_INITIALIZER(&dhcp_opts); + struct hmap dhcpv6_opts = HMAP_INITIALIZER(&dhcpv6_opts); + const struct sbrec_dhcp_options *dhcp_opt_row; + SBREC_DHCP_OPTIONS_TABLE_FOR_EACH (dhcp_opt_row, dhcp_options_table) { + dhcp_opt_add(&dhcp_opts, dhcp_opt_row->name, dhcp_opt_row->code, + dhcp_opt_row->type); + } + + const struct sbrec_dhcpv6_options *dhcpv6_opt_row; + SBREC_DHCPV6_OPTIONS_TABLE_FOR_EACH(dhcpv6_opt_row, dhcpv6_options_table) { + dhcp_opt_add(&dhcpv6_opts, dhcpv6_opt_row->name, dhcpv6_opt_row->code, + dhcpv6_opt_row->type); + } + + struct hmap nd_ra_opts = HMAP_INITIALIZER(&nd_ra_opts); + nd_ra_opts_init(&nd_ra_opts); + + /* Re-parse the related lflows. */ + LIST_FOR_EACH (lrln, ref_list, &rlfn->ref_lflow_head) { + const struct sbrec_logical_flow *lflow = + sbrec_logical_flow_table_get_for_uuid(logical_flow_table, + &lrln->lflow_uuid); + if (!lflow) { + VLOG_DBG("Reprocess lflow "UUID_FMT" for resource type: %d," + " name: %s - not found.", + UUID_ARGS(&lrln->lflow_uuid), + ref_type, ref_name); + continue; + } + VLOG_DBG("Reprocess lflow "UUID_FMT" for resource type: %d," + " name: %s.", + UUID_ARGS(&lrln->lflow_uuid), + ref_type, ref_name); + ofctrl_remove_flows(flow_table, &lrln->lflow_uuid); + if (!consider_logical_flow(sbrec_chassis_by_name, + sbrec_multicast_group_by_name_datapath, + sbrec_port_binding_by_name, + lflow, local_datapaths, + chassis, &dhcp_opts, &dhcpv6_opts, + &nd_ra_opts, addr_sets, port_groups, + active_tunnels, local_lport_ids, + flow_table, group_table, meter_table, + lfrr, conj_id_ofs)) { + ret = false; + break; + } + *changed = true; + } + + LIST_FOR_EACH_SAFE (lrln, next, ref_list, &rlfn->ref_lflow_head) { + ovs_list_remove(&lrln->ref_list); + free(lrln); + } + free(rlfn); + + dhcp_opts_destroy(&dhcp_opts); + dhcp_opts_destroy(&dhcpv6_opts); + nd_ra_opts_destroy(&nd_ra_opts); + return ret; +} + static bool update_conj_id_ofs(uint32_t *conj_id_ofs, uint32_t n_conjs) { diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h index bb5949b..01dda1d 100644 --- a/ovn/controller/lflow.h +++ b/ovn/controller/lflow.h @@ -154,6 +154,28 @@ bool lflow_handle_changed_flows( struct lflow_resource_ref *, uint32_t *conj_id_ofs); +bool lflow_handle_changed_ref( + enum ref_type, + const char *ref_name, + struct ovsdb_idl_index *sbrec_chassis_by_name, + struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath, + struct ovsdb_idl_index *sbrec_port_binding_by_name, + const struct sbrec_dhcp_options_table *, + const struct sbrec_dhcpv6_options_table *, + const struct sbrec_logical_flow_table *, + const struct hmap *local_datapaths, + const struct sbrec_chassis *, + const struct shash *addr_sets, + const struct shash *port_groups, + const struct sset *active_tunnels, + const struct sset *local_lport_ids, + struct ovn_desired_flow_table *, + struct ovn_extend_table *group_table, + struct ovn_extend_table *meter_table, + struct lflow_resource_ref *, + uint32_t *conj_id_ofs, + bool *changed); + void lflow_destroy(void); #endif /* ovn/lflow.h */ diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 261c087..0e445df 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -295,6 +295,29 @@ addr_sets_init(const struct sbrec_address_set_table *address_set_table, } } +static void +addr_sets_update(const struct sbrec_address_set_table *address_set_table, + struct shash *addr_sets, struct sset *new, + struct sset *deleted, struct sset *updated) +{ + const struct sbrec_address_set *as; + SBREC_ADDRESS_SET_TABLE_FOR_EACH_TRACKED (as, address_set_table) { + if (sbrec_address_set_is_deleted(as)) { + expr_const_sets_remove(addr_sets, as->name); + sset_add(deleted, as->name); + } else { + expr_const_sets_add(addr_sets, as->name, + (const char *const *) as->addresses, + as->n_addresses, true); + if (sbrec_address_set_is_new(as)) { + sset_add(new, as->name); + } else { + sset_add(updated, as->name); + } + } + } +} + /* Iterate port groups in the southbound database. Create and update the * corresponding symtab entries as necessary. */ static void @@ -606,6 +629,7 @@ const char *ovs_engine_node_names[] = { struct ed_type_addr_sets { struct shash addr_sets; + bool change_tracked; struct sset new; struct sset deleted; struct sset updated; @@ -616,6 +640,7 @@ en_addr_sets_init(struct engine_node *node) { struct ed_type_addr_sets *as = (struct ed_type_addr_sets *)node->data; shash_init(&as->addr_sets); + as->change_tracked = false; sset_init(&as->new); sset_init(&as->deleted); sset_init(&as->updated); @@ -648,7 +673,32 @@ en_addr_sets_run(struct engine_node *node) addr_sets_init(as_table, &as->addr_sets); + as->change_tracked = false; + node->changed = true; +} + +static bool +addr_sets_sb_address_set_handler(struct engine_node *node) +{ + struct ed_type_addr_sets *as = (struct ed_type_addr_sets *)node->data; + + sset_clear(&as->new); + sset_clear(&as->deleted); + sset_clear(&as->updated); + + struct sbrec_address_set_table *as_table = + (struct sbrec_address_set_table *)EN_OVSDB_GET( + engine_get_input("SB_address_set", node)); + + addr_sets_update(as_table, &as->addr_sets, &as->new, + &as->deleted, &as->updated); + + node->changed = !sset_is_empty(&as->new) || !sset_is_empty(&as->deleted) + || !sset_is_empty(&as->updated); + + as->change_tracked = true; node->changed = true; + return true; } struct ed_type_runtime_data { @@ -1279,6 +1329,124 @@ flow_output_sb_multicast_group_handler(struct engine_node *node) } +static bool +flow_output_addr_sets_handler(struct engine_node *node) +{ + struct ed_type_runtime_data *data = + (struct ed_type_runtime_data *)engine_get_input( + "runtime_data", node)->data; + struct hmap *local_datapaths = &data->local_datapaths; + struct sset *local_lport_ids = &data->local_lport_ids; + struct sset *active_tunnels = &data->active_tunnels; + struct shash *port_groups = &data->port_groups; + struct ed_type_addr_sets *as_data = + (struct ed_type_addr_sets *)engine_get_input("addr_sets", node)->data; + + /* XXX: The change_tracked check may be added to inc-proc framework. */ + if (!as_data->change_tracked) { + return false; + } + struct shash *addr_sets = &as_data->addr_sets; + + struct ovsrec_open_vswitch_table *ovs_table = + (struct ovsrec_open_vswitch_table *)EN_OVSDB_GET( + engine_get_input("OVS_open_vswitch", node)); + struct ovsrec_bridge_table *bridge_table = + (struct ovsrec_bridge_table *)EN_OVSDB_GET( + engine_get_input("OVS_bridge", node)); + const struct ovsrec_bridge *br_int = get_br_int(bridge_table, ovs_table); + const char *chassis_id = get_chassis_id(ovs_table); + + struct ovsdb_idl_index *sbrec_chassis_by_name = + engine_ovsdb_node_get_index( + engine_get_input("SB_chassis", node), + "name"); + const struct sbrec_chassis *chassis = NULL; + if (chassis_id) { + chassis = chassis_lookup_by_name(sbrec_chassis_by_name, chassis_id); + } + + ovs_assert(br_int && chassis); + + struct ed_type_flow_output *fo = + (struct ed_type_flow_output *)node->data; + struct ovn_desired_flow_table *flow_table = &fo->flow_table; + struct ovn_extend_table *group_table = &fo->group_table; + struct ovn_extend_table *meter_table = &fo->meter_table; + uint32_t *conj_id_ofs = &fo->conj_id_ofs; + struct lflow_resource_ref *lfrr = &fo->lflow_resource_ref; + + struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath = + engine_ovsdb_node_get_index( + engine_get_input("SB_multicast_group", node), + "name_datapath"); + + struct ovsdb_idl_index *sbrec_port_binding_by_name = + engine_ovsdb_node_get_index( + engine_get_input("SB_port_binding", node), + "name"); + + struct sbrec_dhcp_options_table *dhcp_table = + (struct sbrec_dhcp_options_table *)EN_OVSDB_GET( + engine_get_input("SB_dhcp_options", node)); + + struct sbrec_dhcpv6_options_table *dhcpv6_table = + (struct sbrec_dhcpv6_options_table *)EN_OVSDB_GET( + engine_get_input("SB_dhcpv6_options", node)); + + struct sbrec_logical_flow_table *logical_flow_table = + (struct sbrec_logical_flow_table *)EN_OVSDB_GET( + engine_get_input("SB_logical_flow", node)); + + bool changed; + const char *as; + + SSET_FOR_EACH (as, &as_data->deleted) { + if (!lflow_handle_changed_ref(REF_TYPE_ADDRSET, as, + sbrec_chassis_by_name, + sbrec_multicast_group_by_name_datapath, + sbrec_port_binding_by_name,dhcp_table, + dhcpv6_table, logical_flow_table, + local_datapaths, chassis, addr_sets, + port_groups, active_tunnels, local_lport_ids, + flow_table, group_table, meter_table, lfrr, + conj_id_ofs, &changed)) { + return false; + } + node->changed = changed || node->changed; + } + SSET_FOR_EACH (as, &as_data->updated) { + if (!lflow_handle_changed_ref(REF_TYPE_ADDRSET, as, + sbrec_chassis_by_name, + sbrec_multicast_group_by_name_datapath, + sbrec_port_binding_by_name,dhcp_table, + dhcpv6_table, logical_flow_table, + local_datapaths, chassis, addr_sets, + port_groups, active_tunnels, local_lport_ids, + flow_table, group_table, meter_table, lfrr, + conj_id_ofs, &changed)) { + return false; + } + node->changed = changed || node->changed; + } + SSET_FOR_EACH (as, &as_data->new) { + if (!lflow_handle_changed_ref(REF_TYPE_ADDRSET, as, + sbrec_chassis_by_name, + sbrec_multicast_group_by_name_datapath, + sbrec_port_binding_by_name,dhcp_table, + dhcpv6_table, logical_flow_table, + local_datapaths, chassis, addr_sets, + port_groups, active_tunnels, local_lport_ids, + flow_table, group_table, meter_table, lfrr, + conj_id_ofs, &changed)) { + return false; + } + node->changed = changed || node->changed; + } + + return true; +} + struct ovn_controller_exit_args { bool *exiting; bool *restart; @@ -1387,9 +1555,9 @@ main(int argc, char *argv[]) /* Add dependencies between inc-proc-engine nodes. */ - engine_add_input(&en_addr_sets, &en_sb_address_set, NULL); + engine_add_input(&en_addr_sets, &en_sb_address_set, addr_sets_sb_address_set_handler); - engine_add_input(&en_flow_output, &en_addr_sets, NULL); + engine_add_input(&en_flow_output, &en_addr_sets, flow_output_addr_sets_handler); engine_add_input(&en_flow_output, &en_runtime_data, NULL); engine_add_input(&en_flow_output, &en_mff_ovn_geneve, NULL); diff --git a/tests/ovn.at b/tests/ovn.at index 70c6c50..49bdf99 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -10975,5 +10975,79 @@ OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected2]) as hv2 start_daemon ovn-controller OVN_CLEANUP([hv1],[hv2]) +AT_CLEANUP + +AT_SETUP([ovn -- Address Set Incremental Processing]) +AT_KEYWORDS([ovn_as_inc]) +AT_SKIP_IF([test $HAVE_PYTHON = no]) +ovn_start + +net_add n1 +sim_add hv1 +as hv1 +ovs-vsctl add-br br-phys +ovn_attach n1 br-phys 192.168.0.10 +ovn-nbctl ls-add ls1 +for i in 1 2; do + ovn-nbctl lsp-add ls1 lp$i \ + -- lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.1.$i" + as hv1 ovs-vsctl \ + -- add-port br-int vif$i \ + -- set Interface vif$i \ + external-ids:iface-id=lp$i +done + +for i in 1 2 3; do + as1_uuid=`ovn-nbctl --wait=hv create addr name=as1` + as2_uuid=`ovn-nbctl --wait=hv create addr name=as2` + ovn-nbctl --wait=hv acl-add ls1 to-lport 200 \ + 'outport=="lp1" && ip4 && ip4.src == {$as1, $as2}' allow-related + ovn-nbctl --wait=hv set addr as1 addresses="10.1.2.10" + AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.10"], [0], [ignore]) + + # Update address set as1 + ovn-nbctl --wait=hv set addr as1 addresses="10.1.2.10 10.1.2.11" + AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.11"], [0], [ignore]) + + # Update address set as2 + ovn-nbctl --wait=hv set addr as2 addresses="10.1.2.12 10.1.2.13" + AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [0], [ignore]) + + # Add another ACL referencing as1 + n_flows_before=`ovs-ofctl dump-flows br-int | grep "10.1.2.10" | wc -l` + ovn-nbctl --wait=hv acl-add ls1 to-lport 200 \ + 'outport=="lp2" && ip4 && ip4.src == $as1' allow-related + n_flows_after=`ovs-ofctl dump-flows br-int | grep "10.1.2.10" | wc -l` + AT_CHECK([test $(expr $n_flows_before \* 2) = $n_flows_after], [0], [ignore]) + + # Remove an ACL + ovn-nbctl --wait=hv acl-del ls1 to-lport 200 \ + 'outport=="lp2" && ip4 && ip4.src == $as1' + n_flows_after=`ovs-ofctl dump-flows br-int | grep "10.1.2.10" | wc -l` + AT_CHECK([test $n_flows_before = $n_flows_after], [0], [ignore]) + + # Remove as1 while it is still used by an ACL, the lflows should be reparsed and + # parsing should fail. + echo "before del as1" + ovn-nbctl list addr | grep as1 + ovn-nbctl --wait=hv destroy addr $as1_uuid + echo "after del as1" + ovn-nbctl list addr | grep as1 + AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.10"], [1], [ignore]) + AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [1], [ignore]) + + # Recreate as1 + as1_uuid=`ovn-nbctl --wait=hv create addr name=as1` + AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [0], [ignore]) + + # Remove ACLs and address sets + ovn-nbctl --wait=hv destroy addr $as1_uuid -- destroy addr $as2_uuid + AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [1], [ignore]) + + ovn-nbctl --wait=hv acl-del ls1 +done + +# Gracefully terminate daemons +OVN_CLEANUP([hv1]) AT_CLEANUP From patchwork Mon Aug 13 17:48:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 957091 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="PyrK2EWw"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41q3LT5dddz9sBD for ; Tue, 14 Aug 2018 03:56:01 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 56237E4C; Mon, 13 Aug 2018 17:48:47 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id A48F1E2E for ; Mon, 13 Aug 2018 17:48:42 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f196.google.com (mail-pg1-f196.google.com [209.85.215.196]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id E89B8765 for ; Mon, 13 Aug 2018 17:48:41 +0000 (UTC) Received: by mail-pg1-f196.google.com with SMTP id y4-v6so7845763pgp.9 for ; Mon, 13 Aug 2018 10:48:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=zGdCLgC7VOZUyNagevHNvQ/UG5AVb3aIh/4Jzy9hPeU=; b=PyrK2EWw756c66YNAFBBI2Tjeff68y2nq5SZUfuks8gMkwB8EoBWh6JDdzSogt0HuU 8C4qlpzFg2P66Fi8GjrP1Fv1z+H1uxWndosHvk06DCDdIVlDN1K2NCkvvex7HtxKoNCY AKF0S+7nspovfBBzVG0Os28eUzjRbVaifybg/NBMcuTn7r3xIZlwJ7SotZPWddj3Ywp6 YxEbCugtwPN/+h1WrUKjOLBcwjr0uhsHj/xluGxK11PwNUrp2izSYKAnyqI1bCQIiqy0 xwIS+WY355jcFwZ/j4a4Jk64x8z1wX7vLMAbWG84gK20761CIYRcbQxIINTJK4+T0UY6 PkmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=zGdCLgC7VOZUyNagevHNvQ/UG5AVb3aIh/4Jzy9hPeU=; b=GDs+Eg5mOt51+kNyo3iakWrhchDAPQ6RM1IPMG50OO4B69OiJf05woqNt1Zwtdgf8Z UXJ23dIZP3iRBog4U3xSeZgtf0ZyY7/upTh+mDARjqK9Rj5mwYxCTOooSIjp+yMdOOeP +0G0THaQ8M4ZhmkvQXndK82m2VPKy2Z82dVQ2EHL4r5KYkAu9vvSUmfjOna1PFBl2H1o Qgbn0KumqQuxlZZIVg3zogQpHA+LrUGKH8zMDC+yyJmVdbas/If+jLRYks4NuJ0d3zlo VRzHoHKFkQAmlksxwCREr6qUBktET3+4MIVv4TV1Ee+dot7+EnyAooi1T3P1HPB6xfDq ZMuQ== X-Gm-Message-State: AOUpUlGe9pT0lSr+qUIKN9fhTOhbr+xz7Ymlzfni600Qz4RA0Y9RC1fH tqz4cGlEqrYL1Fp88JsiK5tSAysC X-Google-Smtp-Source: AA+uWPyDTi5dQz/pH4b0/iN23Yz98zePrAoGlxP5LBWy1DAL6rHtjfo0rZczhfZbPLT8GPLpPw1h/w== X-Received: by 2002:a65:5307:: with SMTP id m7-v6mr15741080pgq.431.1534182521359; Mon, 13 Aug 2018 10:48:41 -0700 (PDT) Received: from localhost.localdomain.localdomain ([216.113.160.70]) by smtp.gmail.com with ESMTPSA id d22-v6sm38068664pfk.69.2018.08.13.10.48.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Aug 2018 10:48:40 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Mon, 13 Aug 2018 10:48:15 -0700 Message-Id: <1534182499-75914-17-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> References: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v5 16/20] ovn-controller: Split port_groups from runtime_data. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org Signed-off-by: Han Zhou --- ovn/controller/ovn-controller.c | 91 +++++++++++++++++++++++++++++++++-------- 1 file changed, 73 insertions(+), 18 deletions(-) diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 0e445df..8509145 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -320,7 +320,7 @@ addr_sets_update(const struct sbrec_address_set_table *address_set_table, /* Iterate port groups in the southbound database. Create and update the * corresponding symtab entries as necessary. */ -static void + static void port_groups_init(const struct sbrec_port_group_table *port_group_table, struct shash *port_groups) { @@ -701,6 +701,56 @@ addr_sets_sb_address_set_handler(struct engine_node *node) return true; } +struct ed_type_port_groups{ + struct shash port_groups; + bool change_tracked; + struct sset new; + struct sset deleted; + struct sset updated; +}; + +static void +en_port_groups_init(struct engine_node *node) +{ + struct ed_type_port_groups *pg = (struct ed_type_port_groups *)node->data; + shash_init(&pg->port_groups); + pg->change_tracked = false; + sset_init(&pg->new); + sset_init(&pg->deleted); + sset_init(&pg->updated); +} + +static void +en_port_groups_cleanup(struct engine_node *node) +{ + struct ed_type_port_groups *pg = (struct ed_type_port_groups *)node->data; + expr_const_sets_destroy(&pg->port_groups); + shash_destroy(&pg->port_groups); + sset_destroy(&pg->new); + sset_destroy(&pg->deleted); + sset_destroy(&pg->updated); +} + +static void +en_port_groups_run(struct engine_node *node) +{ + struct ed_type_port_groups *pg = (struct ed_type_port_groups *)node->data; + + sset_clear(&pg->new); + sset_clear(&pg->deleted); + sset_clear(&pg->updated); + expr_const_sets_destroy(&pg->port_groups); + + struct sbrec_port_group_table *pg_table = + (struct sbrec_port_group_table *)EN_OVSDB_GET( + engine_get_input("SB_port_group", node)); + + port_groups_init(pg_table, &pg->port_groups); + + pg->change_tracked = false; + node->changed = true; +} + struct ed_type_runtime_data { /* Contains "struct local_datapath" nodes. */ struct hmap local_datapaths; @@ -716,7 +766,6 @@ struct ed_type_runtime_data { * _ */ struct sset local_lport_ids; struct sset active_tunnels; - struct shash port_groups; /* connection tracking zones. */ unsigned long ct_zone_bitmap[BITMAP_N_LONGS(MAX_CT_ZONES)]; @@ -739,7 +788,6 @@ en_runtime_data_init(struct engine_node *node) sset_init(&data->local_lports); sset_init(&data->local_lport_ids); sset_init(&data->active_tunnels); - shash_init(&data->port_groups); shash_init(&data->pending_ct_zones); simap_init(&data->ct_zones); @@ -756,9 +804,6 @@ en_runtime_data_cleanup(struct engine_node *node) struct ed_type_runtime_data *data = (struct ed_type_runtime_data *)node->data; - expr_const_sets_destroy(&data->port_groups); - shash_destroy(&data->port_groups); - sset_destroy(&data->local_lports); sset_destroy(&data->local_lport_ids); sset_destroy(&data->active_tunnels); @@ -784,7 +829,6 @@ en_runtime_data_run(struct engine_node *node) struct sset *local_lports = &data->local_lports; struct sset *local_lport_ids = &data->local_lport_ids; struct sset *active_tunnels = &data->active_tunnels; - struct shash *port_groups = &data->port_groups; unsigned long *ct_zone_bitmap = data->ct_zone_bitmap; struct shash *pending_ct_zones = &data->pending_ct_zones; struct simap *ct_zones = &data->ct_zones; @@ -804,7 +848,6 @@ en_runtime_data_run(struct engine_node *node) sset_destroy(local_lports); sset_destroy(local_lport_ids); sset_destroy(active_tunnels); - expr_const_sets_destroy(port_groups); sset_init(local_lports); sset_init(local_lport_ids); sset_init(active_tunnels); @@ -870,11 +913,6 @@ en_runtime_data_run(struct engine_node *node) active_tunnels, local_datapaths, local_lports, local_lport_ids); - struct sbrec_port_group_table *pg_table = - (struct sbrec_port_group_table *)EN_OVSDB_GET( - engine_get_input("SB_port_group", node)); - port_groups_init(pg_table, port_groups); - update_ct_zones(local_lports, local_datapaths, ct_zones, ct_zone_bitmap, pending_ct_zones); @@ -998,7 +1036,6 @@ en_flow_output_run(struct engine_node *node) struct sset *local_lports = &rt_data->local_lports; struct sset *local_lport_ids = &rt_data->local_lport_ids; struct sset *active_tunnels = &rt_data->active_tunnels; - struct shash *port_groups = &rt_data->port_groups; struct simap *ct_zones = &rt_data->ct_zones; struct ed_type_mff_ovn_geneve *ed_mff_ovn_geneve = @@ -1023,6 +1060,11 @@ en_flow_output_run(struct engine_node *node) (struct ed_type_addr_sets *)engine_get_input("addr_sets", node)->data; struct shash *addr_sets = &as_data->addr_sets; + struct ed_type_port_groups *pg_data = + (struct ed_type_port_groups *)engine_get_input( + "port_groups", node)->data; + struct shash *port_groups = &pg_data->port_groups; + const struct sbrec_chassis *chassis = NULL; if (chassis_id) { chassis = chassis_lookup_by_name(sbrec_chassis_by_name, chassis_id); @@ -1117,11 +1159,15 @@ flow_output_sb_logical_flow_handler(struct engine_node *node) struct hmap *local_datapaths = &data->local_datapaths; struct sset *local_lport_ids = &data->local_lport_ids; struct sset *active_tunnels = &data->active_tunnels; - struct shash *port_groups = &data->port_groups; struct ed_type_addr_sets *as_data = (struct ed_type_addr_sets *)engine_get_input("addr_sets", node)->data; struct shash *addr_sets = &as_data->addr_sets; + struct ed_type_port_groups *pg_data = + (struct ed_type_port_groups *)engine_get_input( + "port_groups", node)->data; + struct shash *port_groups = &pg_data->port_groups; + struct ovsrec_open_vswitch_table *ovs_table = (struct ovsrec_open_vswitch_table *)EN_OVSDB_GET( engine_get_input("OVS_open_vswitch", node)); @@ -1135,6 +1181,7 @@ flow_output_sb_logical_flow_handler(struct engine_node *node) engine_ovsdb_node_get_index( engine_get_input("SB_chassis", node), "name"); + const struct sbrec_chassis *chassis = NULL; if (chassis_id) { chassis = chassis_lookup_by_name(sbrec_chassis_by_name, chassis_id); @@ -1338,7 +1385,7 @@ flow_output_addr_sets_handler(struct engine_node *node) struct hmap *local_datapaths = &data->local_datapaths; struct sset *local_lport_ids = &data->local_lport_ids; struct sset *active_tunnels = &data->active_tunnels; - struct shash *port_groups = &data->port_groups; + struct ed_type_addr_sets *as_data = (struct ed_type_addr_sets *)engine_get_input("addr_sets", node)->data; @@ -1348,6 +1395,11 @@ flow_output_addr_sets_handler(struct engine_node *node) } struct shash *addr_sets = &as_data->addr_sets; + struct ed_type_port_groups *pg_data = + (struct ed_type_port_groups *)engine_get_input( + "port_groups", node)->data; + struct shash *port_groups = &pg_data->port_groups; + struct ovsrec_open_vswitch_table *ovs_table = (struct ovsrec_open_vswitch_table *)EN_OVSDB_GET( engine_get_input("OVS_open_vswitch", node)); @@ -1532,11 +1584,13 @@ main(int argc, char *argv[]) struct ed_type_mff_ovn_geneve ed_mff_ovn_geneve; struct ed_type_flow_output ed_flow_output; struct ed_type_addr_sets ed_addr_sets; + struct ed_type_port_groups ed_port_groups; ENGINE_NODE(runtime_data, "runtime_data"); ENGINE_NODE(mff_ovn_geneve, "mff_ovn_geneve"); ENGINE_NODE(flow_output, "flow_output"); ENGINE_NODE(addr_sets, "addr_sets"); + ENGINE_NODE(port_groups, "port_groups"); #define SB_NODE(NAME, NAME_STR) ENGINE_NODE_SB(NAME, NAME_STR); SB_NODES @@ -1556,8 +1610,10 @@ main(int argc, char *argv[]) /* Add dependencies between inc-proc-engine nodes. */ engine_add_input(&en_addr_sets, &en_sb_address_set, addr_sets_sb_address_set_handler); + engine_add_input(&en_port_groups, &en_sb_port_group, NULL); engine_add_input(&en_flow_output, &en_addr_sets, flow_output_addr_sets_handler); + engine_add_input(&en_flow_output, &en_port_groups, NULL); engine_add_input(&en_flow_output, &en_runtime_data, NULL); engine_add_input(&en_flow_output, &en_mff_ovn_geneve, NULL); @@ -1585,7 +1641,6 @@ main(int argc, char *argv[]) engine_add_input(&en_runtime_data, &en_ovs_interface, NULL); engine_add_input(&en_runtime_data, &en_sb_chassis, NULL); - engine_add_input(&en_runtime_data, &en_sb_port_group, NULL); engine_add_input(&en_runtime_data, &en_sb_datapath_binding, NULL); engine_add_input(&en_runtime_data, &en_sb_port_binding, runtime_data_sb_port_binding_handler); engine_add_input(&en_runtime_data, &en_sb_gateway_chassis, NULL); @@ -1752,7 +1807,7 @@ main(int argc, char *argv[]) if (pending_pkt.conn) { if (br_int && chassis) { char *error = ofctrl_inject_pkt(br_int, pending_pkt.flow_s, - &ed_runtime_data.port_groups, + &ed_port_groups.port_groups, &ed_addr_sets.addr_sets); if (error) { unixctl_command_reply_error(pending_pkt.conn, error); From patchwork Mon Aug 13 17:48:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 957092 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="IOxnbKL4"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41q3Lw1Kkvz9sBD for ; Tue, 14 Aug 2018 03:56:24 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 054F6DB2; Mon, 13 Aug 2018 17:48:48 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id C1675E37 for ; Mon, 13 Aug 2018 17:48:43 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pf1-f169.google.com (mail-pf1-f169.google.com [209.85.210.169]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 42D3A765 for ; Mon, 13 Aug 2018 17:48:43 +0000 (UTC) Received: by mail-pf1-f169.google.com with SMTP id x17-v6so8001140pfh.5 for ; Mon, 13 Aug 2018 10:48:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=PdMeo5zDXDWmx6gO/IE/EsJ9morVTelT1vTdSXq5E9U=; b=IOxnbKL4K8nKbKV9uijOS5uIWT4xx6LejyZtK77uNmlvInOfEzNl+lQxemD+u77yAt V0mr4cznsgAbKCggOV9aPsbfSL84fV5jYCxD8KWRhcgWN9DNpnJ9lI88ZAV5kK7HVQDW 01iqSZhUxkUzcS54Yw0CCDAmE6VVmnYpd/T409xF/ZG0/xmVeEygQkKPWEmKpQ+zC8ZD hQ8B1cDgzNpHuZa3t9qungV+Z3li5Gf2lNRlc6N/7oc7ul7vYBKVAa3jpGKJprCCUIHe Di+onfeObudvPgY48Lcqpj/Os6i9m71MKJMsP7KwurRj8nzwSym5hG4VZg6eDzm7K0yH BUTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=PdMeo5zDXDWmx6gO/IE/EsJ9morVTelT1vTdSXq5E9U=; b=b2Q757jsK8Y35koPavDH6Y6nMlAiXDs7HoTYpWT+yYdYZxDWEeHOkh/HKtQEqZn1tH xxCSsC2uyZ5oQzqcU38RxWyBDfXsepzRU0IQ9IUdRd+fXs1qlWCsuNNW25i5P24+UYgI GEPFZPyJzpyQj8Du7x3FnEm6DulXPnxJDubUiZD6ohTAubTzbRr96xFh1JfLFtRMEW63 V70OQUOyF4JCvbONwKfFfHVcIGYvA1yAyGECXSvQrRhGGyKEAyClRLFZlVJI1PxdD5Wb aM2EeBvdZJnzI7JatZuQDlh3YKkk64j/NQ+CWt2hQc/x10dOMyz+E64Y3iPfJVEJSNWv jVRQ== X-Gm-Message-State: AOUpUlGRv82Yf134csBeTeQquZmNxfdpSkjmyDVqkePTq8EpJoEqCWkt rqW1dLaHnslC4bsBVrOqwzM0h1TK X-Google-Smtp-Source: AA+uWPw++f01Thxkr9mHS8/89Ksp6OogO8RFfPrwocf0b2fdHZ/V2b8Q/KJVTGrwwVy+MNEWNa3vBw== X-Received: by 2002:a63:920c:: with SMTP id o12-v6mr18075197pgd.141.1534182522572; Mon, 13 Aug 2018 10:48:42 -0700 (PDT) Received: from localhost.localdomain.localdomain ([216.113.160.70]) by smtp.gmail.com with ESMTPSA id d22-v6sm38068664pfk.69.2018.08.13.10.48.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Aug 2018 10:48:42 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Mon, 13 Aug 2018 10:48:16 -0700 Message-Id: <1534182499-75914-18-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> References: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v5 17/20] ovn-controller: Incremental processing for port-group changes. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org Signed-off-by: Han Zhou --- ovn/controller/lflow.h | 3 +- ovn/controller/ovn-controller.c | 110 ++++++++++++++++++++++++++++++++++------ 2 files changed, 97 insertions(+), 16 deletions(-) diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h index 01dda1d..b90f971 100644 --- a/ovn/controller/lflow.h +++ b/ovn/controller/lflow.h @@ -70,7 +70,8 @@ struct uuid; #define LOG_PIPELINE_LEN 24 enum ref_type { - REF_TYPE_ADDRSET + REF_TYPE_ADDRSET, + REF_TYPE_PORTGROUP }; /* Maintains the relationship for a pair of named resource and diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 8509145..99e9016 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -333,6 +333,29 @@ port_groups_init(const struct sbrec_port_group_table *port_group_table, } static void +port_groups_update(const struct sbrec_port_group_table *port_group_table, + struct shash *port_groups, struct sset *new, + struct sset *deleted, struct sset *updated) +{ + const struct sbrec_port_group *pg; + SBREC_PORT_GROUP_TABLE_FOR_EACH_TRACKED (pg, port_group_table) { + if (sbrec_port_group_is_deleted(pg)) { + expr_const_sets_remove(port_groups, pg->name); + sset_add(deleted, pg->name); + } else { + expr_const_sets_add(port_groups, pg->name, + (const char *const *) pg->ports, + pg->n_ports, false); + if (sbrec_port_group_is_new(pg)) { + sset_add(new, pg->name); + } else { + sset_add(updated, pg->name); + } + } + } +} + +static void update_ssl_config(const struct ovsrec_ssl_table *ssl_table) { const struct ovsrec_ssl *ssl = ovsrec_ssl_table_first(ssl_table); @@ -751,6 +774,30 @@ en_port_groups_run(struct engine_node *node) node->changed = true; } +static bool +port_groups_sb_port_group_handler(struct engine_node *node) +{ + struct ed_type_port_groups *pg = (struct ed_type_port_groups *)node->data; + + sset_clear(&pg->new); + sset_clear(&pg->deleted); + sset_clear(&pg->updated); + + struct sbrec_port_group_table *pg_table = + (struct sbrec_port_group_table *)EN_OVSDB_GET( + engine_get_input("SB_port_group", node)); + + port_groups_update(pg_table, &pg->port_groups, &pg->new, + &pg->deleted, &pg->updated); + + node->changed = !sset_is_empty(&pg->new) || !sset_is_empty(&pg->deleted) + || !sset_is_empty(&pg->updated); + + pg->change_tracked = true; + node->changed = true; + return true; +} + struct ed_type_runtime_data { /* Contains "struct local_datapath" nodes. */ struct hmap local_datapaths; @@ -1377,7 +1424,8 @@ flow_output_sb_multicast_group_handler(struct engine_node *node) } static bool -flow_output_addr_sets_handler(struct engine_node *node) +_flow_output_resource_ref_handler(struct engine_node *node, + enum ref_type ref_type) { struct ed_type_runtime_data *data = (struct ed_type_runtime_data *)engine_get_input( @@ -1388,11 +1436,6 @@ flow_output_addr_sets_handler(struct engine_node *node) struct ed_type_addr_sets *as_data = (struct ed_type_addr_sets *)engine_get_input("addr_sets", node)->data; - - /* XXX: The change_tracked check may be added to inc-proc framework. */ - if (!as_data->change_tracked) { - return false; - } struct shash *addr_sets = &as_data->addr_sets; struct ed_type_port_groups *pg_data = @@ -1451,10 +1494,35 @@ flow_output_addr_sets_handler(struct engine_node *node) engine_get_input("SB_logical_flow", node)); bool changed; - const char *as; + const char *ref_name; + struct sset *new, *updated, *deleted; + + switch (ref_type) { + case REF_TYPE_ADDRSET: + /* XXX: The change_tracked check may be added to inc-proc + * framework. */ + if (!as_data->change_tracked) { + return false; + } + new = &as_data->new; + updated = &as_data->updated; + deleted = &as_data->deleted; + break; + case REF_TYPE_PORTGROUP: + if (!pg_data->change_tracked) { + return false; + } + new = &pg_data->new; + updated = &pg_data->updated; + deleted = &pg_data->deleted; + break; + default: + OVS_NOT_REACHED(); + } + - SSET_FOR_EACH (as, &as_data->deleted) { - if (!lflow_handle_changed_ref(REF_TYPE_ADDRSET, as, + SSET_FOR_EACH (ref_name, deleted) { + if (!lflow_handle_changed_ref(ref_type, ref_name, sbrec_chassis_by_name, sbrec_multicast_group_by_name_datapath, sbrec_port_binding_by_name,dhcp_table, @@ -1467,8 +1535,8 @@ flow_output_addr_sets_handler(struct engine_node *node) } node->changed = changed || node->changed; } - SSET_FOR_EACH (as, &as_data->updated) { - if (!lflow_handle_changed_ref(REF_TYPE_ADDRSET, as, + SSET_FOR_EACH (ref_name, updated) { + if (!lflow_handle_changed_ref(ref_type, ref_name, sbrec_chassis_by_name, sbrec_multicast_group_by_name_datapath, sbrec_port_binding_by_name,dhcp_table, @@ -1481,8 +1549,8 @@ flow_output_addr_sets_handler(struct engine_node *node) } node->changed = changed || node->changed; } - SSET_FOR_EACH (as, &as_data->new) { - if (!lflow_handle_changed_ref(REF_TYPE_ADDRSET, as, + SSET_FOR_EACH (ref_name, new) { + if (!lflow_handle_changed_ref(ref_type, ref_name, sbrec_chassis_by_name, sbrec_multicast_group_by_name_datapath, sbrec_port_binding_by_name,dhcp_table, @@ -1499,6 +1567,18 @@ flow_output_addr_sets_handler(struct engine_node *node) return true; } +static bool +flow_output_addr_sets_handler(struct engine_node *node) +{ + return _flow_output_resource_ref_handler(node, REF_TYPE_ADDRSET); +} + +static bool +flow_output_port_groups_handler(struct engine_node *node) +{ + return _flow_output_resource_ref_handler(node, REF_TYPE_PORTGROUP); +} + struct ovn_controller_exit_args { bool *exiting; bool *restart; @@ -1610,10 +1690,10 @@ main(int argc, char *argv[]) /* Add dependencies between inc-proc-engine nodes. */ engine_add_input(&en_addr_sets, &en_sb_address_set, addr_sets_sb_address_set_handler); - engine_add_input(&en_port_groups, &en_sb_port_group, NULL); + engine_add_input(&en_port_groups, &en_sb_port_group, port_groups_sb_port_group_handler); engine_add_input(&en_flow_output, &en_addr_sets, flow_output_addr_sets_handler); - engine_add_input(&en_flow_output, &en_port_groups, NULL); + engine_add_input(&en_flow_output, &en_port_groups, flow_output_port_groups_handler); engine_add_input(&en_flow_output, &en_runtime_data, NULL); engine_add_input(&en_flow_output, &en_mff_ovn_geneve, NULL); From patchwork Mon Aug 13 17:48:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 957093 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="bEode72V"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41q3MK30mHz9sBD for ; Tue, 14 Aug 2018 03:56:45 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id CE970E5F; Mon, 13 Aug 2018 17:48:48 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 54932E1B for ; Mon, 13 Aug 2018 17:48:44 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pf1-f193.google.com (mail-pf1-f193.google.com [209.85.210.193]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 031C3765 for ; Mon, 13 Aug 2018 17:48:43 +0000 (UTC) Received: by mail-pf1-f193.google.com with SMTP id l9-v6so7989991pff.9 for ; Mon, 13 Aug 2018 10:48:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=QNEYzdyqr6EkNoulvqvEEEHNYeHlAV2XIgWV107pa5g=; b=bEode72VGm3YqIXosv5tsqQuL9bQa2Q6bTbDDPT/H2inQlkikmrKFkE+2gSQBZ+egI wr0DHzJoga/UrROBeefoTyPB5ILun/eCXMVsQ6nCpHJcnKTQpxW69dtoUzERGDnUgTMl ZGJp6FISok9dC5r8BT+qfkOeE8nBhyWiKgg2YBCyj0Bxq4Cmwmo9wsJeFFSGzf3vVUhB m3K59NRFKN1vS3GUvt5GKfT2lWkJSfxCuLb+RO/d6jfKMRXTV99O9UQ6InTU3xZIBGoA MoLN02jEYhQZiMf0PWIV+jbQOtfBGqPjlBexQWNXBA9sAgWvenxjGzxXBQHsy18h872o gYiA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=QNEYzdyqr6EkNoulvqvEEEHNYeHlAV2XIgWV107pa5g=; b=qjhZzQM0gWDIDSudk5IDZjXYjuCafKLToayoMXgQAoG4vCnwf4R2cRkxDxV0iAWvHN GwaX7z4Vxom5dbjE0P/0yswzgtQFCGIXWjCY6tQHK9QGMUxSsFWji4yZBeCVSwL7HYvR 5345JTzaFX9vlmG9FI4jdnazs9di12f4NH7YAp5XD3htSXruZiUTyJsVA1wgX2v7NWW4 kOpghtP0suZn0ErRfqc22reOQd2pBuIxaUo62fiLPT0cBT476+2XIsVbqwK2O2Px6ppS HZRTnwYhFoFDq8Anjo3mHlCW3JW03S9uvEN5k9wDcUA9qKWB0SWfGgCjIXrIWMfz7tc4 tO+w== X-Gm-Message-State: AOUpUlFijoOiApX5yU+jB2p4F8raIw46QlSSuc0WTnEyEyP2hYA72Qx2 xJfullGrpaBARQJvUpvgKRaDF1Xe X-Google-Smtp-Source: AA+uWPwKLEWhincvGRF3SsOgQt8WsUvfn9GPyHuDPHrRGYd78U+2LJdU+mej+s5YiiAUshlXaKMY7A== X-Received: by 2002:a65:5144:: with SMTP id g4-v6mr17831380pgq.21.1534182523441; Mon, 13 Aug 2018 10:48:43 -0700 (PDT) Received: from localhost.localdomain.localdomain ([216.113.160.70]) by smtp.gmail.com with ESMTPSA id d22-v6sm38068664pfk.69.2018.08.13.10.48.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Aug 2018 10:48:42 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Mon, 13 Aug 2018 10:48:17 -0700 Message-Id: <1534182499-75914-19-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> References: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Jakub Sitnicki Subject: [ovs-dev] [PATCH v5 18/20] coverage: Add command for reading counter value. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Jakub Sitnicki From: Jakub Sitnicki Facilitate checking coverage counters from scripts and tests with a new coverage/read-counter command that gets the total count for a counter. Same could be achieved by scraping the output of coverage/show command but the difficulties there are that output is in human readable format and zero-value counters are not listed. Signed-off-by: Jakub Sitnicki Acked-by: Han Zhou --- lib/coverage-unixctl.man | 2 ++ lib/coverage.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/lib/coverage-unixctl.man b/lib/coverage-unixctl.man index 8e5df81..81eb939 100644 --- a/lib/coverage-unixctl.man +++ b/lib/coverage-unixctl.man @@ -11,3 +11,5 @@ debugging. Displays the averaged per-second rates for the last few seconds, the last minute and the last hour, and the total counts of all of the coverage counters. +.IP "\fBcoverage/read-counter\fR \fIcounter\fR" +Displays the total count for the given coverage \fIcounter\fR. diff --git a/lib/coverage.c b/lib/coverage.c index 6cef826..a95b6aa 100644 --- a/lib/coverage.c +++ b/lib/coverage.c @@ -44,6 +44,8 @@ static unsigned int idx_count = 0; static void coverage_read(struct svec *); static unsigned int coverage_array_sum(const unsigned int *arr, const unsigned int len); +static bool coverage_read_counter(const char *name, + unsigned long long int *count); /* Registers a coverage counter with the coverage core */ void @@ -72,11 +74,32 @@ coverage_unixctl_show(struct unixctl_conn *conn, int argc OVS_UNUSED, svec_destroy(&lines); } +static void +coverage_unixctl_read_counter(struct unixctl_conn *conn, int argc OVS_UNUSED, + const char *argv[], void *aux OVS_UNUSED) +{ + unsigned long long count; + char *reply; + bool ok; + + ok = coverage_read_counter(argv[1], &count); + if (!ok) { + unixctl_command_reply_error(conn, "No such counter"); + return; + } + + reply = xasprintf("%llu\n", count); + unixctl_command_reply(conn, reply); + free(reply); +} + void coverage_init(void) { unixctl_command_register("coverage/show", "", 0, 0, coverage_unixctl_show, NULL); + unixctl_command_register("coverage/read-counter", "COUNTER", 1, 1, + coverage_unixctl_read_counter, NULL); } /* Sorts coverage counters in descending order by total, within equal @@ -372,3 +395,22 @@ coverage_array_sum(const unsigned int *arr, const unsigned int len) ovs_mutex_unlock(&coverage_mutex); return sum; } + +static bool +coverage_read_counter(const char *name, unsigned long long int *count) +{ + for (size_t i = 0; i < n_coverage_counters; i++) { + struct coverage_counter *c = coverage_counters[i]; + + if (!strcmp(c->name, name)) { + ovs_mutex_lock(&coverage_mutex); + c->total += c->count(); + *count = c->total; + ovs_mutex_unlock(&coverage_mutex); + + return true; + } + } + + return false; +} From patchwork Mon Aug 13 17:48:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 957098 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="rTAbEXd1"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41q3Nb4zJXz9s7Q for ; Tue, 14 Aug 2018 03:57:51 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 56176E6A; Mon, 13 Aug 2018 17:48:51 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 274B5E3C for ; Mon, 13 Aug 2018 17:48:46 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f195.google.com (mail-pg1-f195.google.com [209.85.215.195]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 01F4C788 for ; Mon, 13 Aug 2018 17:48:44 +0000 (UTC) Received: by mail-pg1-f195.google.com with SMTP id a14-v6so7841162pgv.10 for ; Mon, 13 Aug 2018 10:48:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=x7AAkIM7a1o42oZFo1wpX39wC2sGAAO8b5be5UseScE=; b=rTAbEXd160M6zT5inQLv8YwYir/uz+EM2GuWYBNcclryL2XEJ1jhZdKisqUO9WGM6t m4JKrKLNwTkuO93KLLd1hpTcrw/pgFwUBTcMZuIqVvmRDEAW7JtHiulSLSXL4SHm/61V NROwKuGod5byF/pUAaOMnXz81/UYVEAzB5ON6NeI8trABS0l8We8i9iGqZSR2LhDJXnH 1VNancWr0/yjUF+V8EcdaDmAoxRybbDmYqAPCPo+82+O1Ozkr52PqDO2Sd/abJMjixEU tDjWW9YaOFSF1ps8Li+h2YwYvw0zEWNN9TOO2scy1Q6Ic25nmUjo04L3LIsRDHMi/49L U57w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=x7AAkIM7a1o42oZFo1wpX39wC2sGAAO8b5be5UseScE=; b=PRWhl0oUupc6MrWA+Wpp1KatMMV0fbEpuyF9U68Nd3a2sfmYZEiB0WTsbZ6y+4ea5M c/6inc0hwX90LwfLOBoxoYexxDwn03Wgvo10KZokMY8mgLGOg2Hi+iGrI1Qx8Vc6VAOh xpCByAOAwr8FFwZxjg8QUNJBTPf9txIIgKnkX1GGIqIq7fUAYHN4PMkhKXNzEPvlhJ2V qaEO+lt3Bl/YQgRRudFqEu4Zqt8Y1CmCn1yQUraDB6+NhUkqpbXgLqfjYOYWjl0E/9uC QuLekGqhsGLEVrsxJBOa+3HA2kvxpQjHzidRHkqJ4Fu1D6wTzC6aqkW1BRWWIhZsmH4f I2+Q== X-Gm-Message-State: AOUpUlHUayuY3FTOVJsB0fR26moysRukR9nJd8J4QGQKJdOP1aC23uql dB7xxj9YmraUUMwRBt4nn/KbjwYV X-Google-Smtp-Source: AA+uWPwQlat5gUmemzRczCx++YaTZZ262HhG3JZfrwrPvmREAzC/DKAPKd8Se4ahJvxYoV5hpWvV3Q== X-Received: by 2002:a63:524e:: with SMTP id s14-v6mr18177089pgl.35.1534182524154; Mon, 13 Aug 2018 10:48:44 -0700 (PDT) Received: from localhost.localdomain.localdomain ([216.113.160.70]) by smtp.gmail.com with ESMTPSA id d22-v6sm38068664pfk.69.2018.08.13.10.48.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Aug 2018 10:48:43 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Mon, 13 Aug 2018 10:48:18 -0700 Message-Id: <1534182499-75914-20-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> References: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Jakub Sitnicki Subject: [ovs-dev] [PATCH v5 19/20] ovn: Test for full logical flow processing in ovn-controller. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Jakub Sitnicki From: Jakub Sitnicki Add a test that performs typical operations of creating & destroying logical routers, switches, ports, address sets and ACLs while checking if they trigger full logical flow processing in the ovn-controller. This way confirm that incremental processing is taking effect when we expect it to. Place the new test in a separate module - tests/ovn-performance.at, instead of the usual tests/ovn.at as it doesn't test OVN's functionality but rather a performance aspect of ovn-controller. Signed-off-by: Jakub Sitnicki Acked-by: Han Zhou --- tests/automake.mk | 3 +- tests/ovn-performance.at | 389 +++++++++++++++++++++++++++++++++++++++++++++++ tests/testsuite.at | 1 + 3 files changed, 392 insertions(+), 1 deletion(-) create mode 100644 tests/ovn-performance.at diff --git a/tests/automake.mk b/tests/automake.mk index 8224e5a..e1b9140 100644 --- a/tests/automake.mk +++ b/tests/automake.mk @@ -105,7 +105,8 @@ TESTSUITE_AT = \ tests/ovn-controller-vtep.at \ tests/mcast-snooping.at \ tests/packet-type-aware.at \ - tests/nsh.at + tests/nsh.at \ + tests/ovn-performance.at SYSTEM_KMOD_TESTSUITE_AT = \ tests/system-common-macros.at \ diff --git a/tests/ovn-performance.at b/tests/ovn-performance.at new file mode 100644 index 0000000..671dd6e --- /dev/null +++ b/tests/ovn-performance.at @@ -0,0 +1,389 @@ +# +# Tests targeting performance of OVN components. +# + +m4_divert_push([PREPARE_TESTS]) + +# vec_cmp VALUE_VEC OP-VALUE_VEC +# +# Compares each value from VALUE_VEC to the operator-value pair from the +# OP-VALUE_VEC. +# +# VALUE_VEC must be a list of values separated by a character from $IFS. +# OP-VALUE_VEC must be a list of operator-value expressions separated by a +# character from $IFS. Operator-value expressions cannot contain any characters +# from $IFS like spaces. '=' is treated as an equality operator ('==') for +# conciseness. +# +# Returns the result of each comparison as a list of boolean values (0 or 1) +# separated by a new-line character. +vec_cmp() { + local a b i j + + i=0 + for a in $1; do + j=0 + for b in $2; do + if test $i -eq $j; then + # Replace assignment '=' with equality comparison '==' + case "$b" in + =[[0-9]]*) b="=$b" ;; + esac + + echo $(($a $b)) + break + fi + j=$((j + 1)) + done + i=$((i + 1)) + done +} + +# vec_sub VEC_A VEC_B +# +# Subtracts two vectors: +# +# VEC_A = [a1, a2, ...] +# VEC_B = [b1, b2, ...] +# OUT = [(a1 - b1), (a2 - b2), ...] +# +# VEC_A and VEC_B must be lists of values separated by a character from $IFS. +vec_sub() { + local a b i j + + i=0 + for a in $1; do + j=0 + for b in $2; do + if test $i -eq $j; then + echo $((a - b)) + break + fi + j=$((j + 1)) + done + i=$((i + 1)) + done +} + +# vec_fold VEC OP +# +# Reduces a vector to a single value by applying the binary operator OP (i.e., +# one that requires two arguments) cumulatively to all vector elements from left +# to right: +# +# VEC = [e1, e2, e3 ...] +# OUT = (...((e1 OP e2) OP e3) OP ...) +# +# VEC must be a list of values separated by a character from $IFS. +vec_fold() { + local first op prod + + first=1 + op=$2 + for a in $1; do + if test $first -eq 1; then + prod=$a + first=0 + else + prod=$((prod $op a)) + fi + done + echo $prod +} + +# read_counters SANDBOXES TARGET COUNTER +# +# Prints out the coverage COUNTER for the TARGET in each of the SANDBOXES. +# +# SANDBOXES must be a list of strings separated by a character from $IFS. +read_counters() { + local sims="$1" target="$2" counter="$3" + + for sim in $sims; do + as $sim ovs-appctl -t "$target" coverage/read-counter "$counter" || return 1 + done +} + +# counter_delta_ SANDBOXES TARGET COUNTER COMMAND +# +# Runs the COMMAND and reports the COUNTER change registered during the command +# run for the given TARGET in each of the SANDBOXES. +counter_delta_() { + local sims="$1" target="$2" counter="$3" cmd="$4" + local before after + + before=$(read_counters "$sims" "$target" "$counter") || return 1 + eval "$cmd" >/dev/null || return 1 + after=$(read_counters "$sims" "$target" "$counter") || return 1 + + vec_sub "$after" "$before" +} + +# counter_delta SANDBOXES TARGET COUNTER COMMAND +# +# Same as counter_delta_ but also prints the COUNTER values together with the +# COMMAND to standard error. +counter_delta() { + local cmd="$4" + local v + + v=$(counter_delta_ "$@") || return 1 + + # Dump the counters and the command for troubleshooting + echo "$v" | tr '\n' '\t' >&2 + echo "$cmd" >&2 + + echo "$v" +} + +# vec_cmp_counter_delta SANDBOXES TARGET COUNTER CONDS COMMAND +# +# Check if COUNTER change in the TARGET app in each of the SANDBOXES after +# running the COMMAND meets the conditions listed as operator-value pairs in +# CONDS. +vec_cmp_counter_delta() { + local v + + v=$(counter_delta "$1" "$2" "$3" "$5") || return 1 + v=$(vec_cmp "$v" "$4") || return 1 + v=$(vec_fold "$v" "&&") || return 1 + + echo "$v" +} + +# cmp_counter_delta SANDBOXES TARGET COUNTER COND COMMAND +# +# Check if COUNTER change in the TARGET app in each of the SANDBOXES after +# running the COMMAND meets the COND condition given as a operator-value pair. +cmp_counter_delta() { + local conds="" + + # Use the same condition for each sandbox + for _ in $1; do + conds="$conds $4" + done + + vec_cmp_counter_delta "$1" "$2" "$3" "$conds" "$5" +} + +m4_divert_pop([PREPARE_TESTS]) + +# CHECK_COUNTER_DELTA_IS_ZERO SANDBOXES TARGET COUNTER COMMAND +# +# Runs the COMMAND and checks if the COUNTER value for the TARGET in all of +# the SANDBOXES did not change. +m4_define([CHECK_COUNTER_DELTA_IS_ZERO],[ + rv=$(cmp_counter_delta "$1" "$2" "$3" "=0" "$4") + rc=$? + AT_CHECK([test $rc -eq 0 -a $rv -eq 1]) +]) + +# CHECK_COUNTER_DELTA_IS_NOT_ZERO SANDBOXES TARGET COUNTER COMMAND +# +# Runs the COMMAND and checks if the COUNTER value for the TARGET in +# all of the SANDBOXES has changed. +m4_define([CHECK_COUNTER_DELTA_IS_NOT_ZERO],[ + rv=$(cmp_counter_delta "$1" "$2" "$3" ">0" "$4") + rc=$? + AT_CHECK([test $rc -eq 0 -a $rv -eq 1]) +]) + +# CHECK_COUNTER_DELTA_COND SANDBOXES TARGET COUNTER CONDS COMMAND +# +# Runs the COMMAND and checks if the COUNTER value for the TARGET in all of the +# SANDBOXES satisfies the conditions listed in CONDS. +m4_define([CHECK_COUNTER_DELTA_COND],[ + rv=$(vec_cmp_counter_delta "$1" "$2" "$3" "$4" "$5") + rc=$? + AT_CHECK([test $rc -eq 0 -a $rv -eq 1]) +]) + +# OVN_CONTROLLER_EXPECT_HIT SANDBOXES COUNTER COMMAND +# +# Checks if the COUNTER value has changed for any of the ovn-controller +# processes in the SANDBOXES when the COMMAND was run. +m4_define([OVN_CONTROLLER_EXPECT_HIT],[ + CHECK_COUNTER_DELTA_IS_NOT_ZERO([$1], [ovn-controller], [$2], [$3]) +]) + +# OVN_CONTROLLER_EXPECT_NO_HIT SANDBOXES COUNTER COMMAND +# +# Checks if the COUNTER value has not changed for any of the ovn-controller +# processes in the SANDBOXES when the COMMAND was run. +m4_define([OVN_CONTROLLER_EXPECT_NO_HIT],[ + CHECK_COUNTER_DELTA_IS_ZERO([$1], [ovn-controller], [$2], [$3]) +]) + +# OVN_CONTROLLER_EXPECT_HIT_COND SANDBOXES COUNTER CONDS COMMAND +# +# Checks if the change of the COUNTER value, when the COMMAND was run, of the +# ovn-controller process in each of the SANDBOXES meets the conditions in +# CONDS. CONDS must be a list of operator-value pairs, for example "[>0 =0]", +# following the same order as SANDBOXES. +m4_define([OVN_CONTROLLER_EXPECT_HIT_COND],[ + CHECK_COUNTER_DELTA_COND([$1], [ovn-controller], [$2], [$3], [$4]) +]) + +AT_SETUP([ovn -- ovn-controller incremental processing]) +# Check which operations the trigger full logical flow processing. +# +# Create and destroy logical routers, switches, ports, address sets and ACLs +# while counting calls to lflow_run() in ovn-controller. + +ovn_start +net_add n1 +for i in 1 2; do + sim_add hv$i + as hv$i + ovs-vsctl add-br br-phys + ovn_attach n1 br-phys 192.168.0.$i +done + +# Add router lr1 +OVN_CONTROLLER_EXPECT_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl --wait=hv lr-add lr1] +) + +for i in 1 2; do + ls=ls$i + lsp=$ls-lr1 + lrp=lr1-$ls + + # Add switch $ls + OVN_CONTROLLER_EXPECT_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl --wait=hv ls-add $ls] + ) + OVN_CONTROLLER_EXPECT_NO_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl --wait=hv add Logical_Switch $ls other_config subnet=10.0.$i.0/24] + ) + + # Add router port to $ls + OVN_CONTROLLER_EXPECT_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl --wait=hv lrp-add lr1 $lrp 02:00:00:00:0$i:01 10.0.$i.1/24] + ) + OVN_CONTROLLER_EXPECT_NO_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl --wait=hv lsp-add $ls $lsp] + ) + OVN_CONTROLLER_EXPECT_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl --wait=hv lsp-set-type $lsp router] + ) + OVN_CONTROLLER_EXPECT_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl --wait=hv lsp-set-addresses $lsp router] + ) +done + +for i in 1 2; do + j=$((i%2 + 1)) + as=as$i + ls=ls$i + lp=lp$i + vif=vif$i + + # Add port $lp + OVN_CONTROLLER_EXPECT_NO_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl --wait=hv lsp-add $ls $lp] + ) + OVN_CONTROLLER_EXPECT_NO_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl --wait=hv lsp-set-addresses $lp "dynamic"] + ) + OVN_CONTROLLER_EXPECT_NO_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl wait-until Logical_Switch_Port $lp dynamic_addresses!=[[]] && + ovn-nbctl --wait=hv sync] + ) + OVN_CONTROLLER_EXPECT_NO_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl get Logical_Switch_Port $lp dynamic_addresses && + ovn-nbctl --wait=hv sync] + ) + + # Add address set $as + OVN_CONTROLLER_EXPECT_NO_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl --wait=hv create Address_Set name="$as"] + ) + OVN_CONTROLLER_EXPECT_NO_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl --wait=hv add Address_Set "$as" addresses "10.0.$i.10"] + ) + + # Add ACLs for port $lp + OVN_CONTROLLER_EXPECT_NO_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl --wait=hv acl-add $ls to-lport 1001 'outport == \"$lp\" && ip4.src == \\$$as' allow] + ) + OVN_CONTROLLER_EXPECT_NO_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl --wait=hv acl-add $ls to-lport 1000 'outport == \"$lp\"' drop] + ) + + # Bind port $lp and wait for it to come up + OVN_CONTROLLER_EXPECT_HIT_COND( + [hv$i hv$j], [lflow_run], [>0 =0], + [as hv$i ovs-vsctl add-port br-int $vif -- set Interface $vif external-ids:iface-id=$lp && + ovn-nbctl wait-until Logical_Switch_Port $lp 'up=true' && + ovn-nbctl --wait=hv sync] + ) +done + +for i in 1 2; do + j=$((i%2 + 1)) + as=as$i + ls=ls$i + lp=lp$i + + # Delete port $lp + OVN_CONTROLLER_EXPECT_HIT_COND( + [hv$i hv$j], [lflow_run], [>0 =0], + [ovn-nbctl --wait=hv lsp-del $lp] + ) + + # Delete ACLs for port $lp + OVN_CONTROLLER_EXPECT_NO_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl --wait=hv acl-del $ls to-lport 1001 'outport == \"$lp\" && ip4.src == \\$$as'] + ) + OVN_CONTROLLER_EXPECT_NO_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl --wait=hv acl-del $ls to-lport 1000 'outport == \"$lp\"'] + ) + + # Delete address set $as + OVN_CONTROLLER_EXPECT_NO_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl --wait=hv remove Address_Set "$as" addresses "10.0.$i.10"] + ) + OVN_CONTROLLER_EXPECT_NO_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl --wait=hv destroy Address_Set "$as"] + ) +done + +for i in 1 2; do + ls=ls$i + + # Delete switch $ls + OVN_CONTROLLER_EXPECT_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl --wait=hv ls-del $ls] + ) +done + +# Delete router lr1 +OVN_CONTROLLER_EXPECT_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl --wait=hv lr-del lr1] +) + +OVN_CLEANUP([hv1], [hv2]) + +AT_CLEANUP diff --git a/tests/testsuite.at b/tests/testsuite.at index 15c385e..c769770 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -80,3 +80,4 @@ m4_include([tests/ovn-controller-vtep.at]) m4_include([tests/mcast-snooping.at]) m4_include([tests/packet-type-aware.at]) m4_include([tests/nsh.at]) +m4_include([tests/ovn-performance.at]) From patchwork Mon Aug 13 17:48:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 957097 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="RAfPLYzd"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41q3Mx5Bs7z9sBD for ; Tue, 14 Aug 2018 03:57:17 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id A3E73E62; Mon, 13 Aug 2018 17:48:49 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 96B9EE2A for ; Mon, 13 Aug 2018 17:48:45 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f45.google.com (mail-pl0-f45.google.com [209.85.160.45]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 507567C4 for ; Mon, 13 Aug 2018 17:48:45 +0000 (UTC) Received: by mail-pl0-f45.google.com with SMTP id w3-v6so7201165plq.2 for ; Mon, 13 Aug 2018 10:48:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Jd82j5JqZlnSRfdA4YGZLHnsTPQpG0D5zJPMmJC2vlI=; b=RAfPLYzdytR9uwf87i/4rOdWtn/vzuYp9mq4RfPSpW7uQlVLPfWnf+sGhHZdWrQ1Oz af4k9zpC0Id05eG6ZwAgz1xxAnO70ftEk8H7sHc4fsNpe9Cq6/BP1Xn64cIM9cZWM2oN bVGJRxPnmpr5unMX9A/wrKYpeUIVgwRPjXnHWpehkgtOc4mSjvINpSDPI1gMyRlgiwEI VJ6fZTPMJYHNuPzOcYD7zjII/Jky14Sk0t6zg1EPESV0N+vzaehI1IXj7KaRF825gB6q WK/UWHESgJujsgMoP9pl1OzO2YBMUL4k3F/32vI561f+UFKARAFnNh/fmft2SNdW0+C4 bIwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Jd82j5JqZlnSRfdA4YGZLHnsTPQpG0D5zJPMmJC2vlI=; b=hDruaWa+I+cgdQJIWBSRmOkKCgT/TENwV7a/zEQGT4mDOOOkWrda/bmzXNJtJw6f/u LjRfXOErOT9ZdxoUwL2aue56xyPTmqmimK/parz/AQfHOO+cESNWJgzax9VVeSoNaOra WHm4alDvBVL1eoyyXnNQzLZ670juLKJTLpxLIpXLyOFny46nU1/n7e0z89qeBPHRIzwc vMRY33kxJBgXTOniLGeYDRDw61+NYhN+/rj2K9B5oRQVRqKfpf1MWPjkKId9IgHbGlNb bt2DnxDmHegemQN92mk4PWx3ej9I+KN7qBC8OJM6S7Jdw1ZxfKsYw6G7LOmJ15jZggUD 2pgw== X-Gm-Message-State: AOUpUlGDL2pOHjnE1GOnmPuP6x3ZET1W8xOovdMb9NCmPqpWi4tdyahl RaDieSl9aaNdPO+NgJ5rQYzLetPx X-Google-Smtp-Source: AA+uWPzSjHate5Drpn5Rl0y2Ly+HQMolEhOw8LRTy9oLTmcuwzZ7Hip4hJ6pmPDftOA2F62oQrJ1Pw== X-Received: by 2002:a17:902:a987:: with SMTP id bh7-v6mr17866143plb.182.1534182524771; Mon, 13 Aug 2018 10:48:44 -0700 (PDT) Received: from localhost.localdomain.localdomain ([216.113.160.70]) by smtp.gmail.com with ESMTPSA id d22-v6sm38068664pfk.69.2018.08.13.10.48.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Aug 2018 10:48:44 -0700 (PDT) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Mon, 13 Aug 2018 10:48:19 -0700 Message-Id: <1534182499-75914-21-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> References: <1534182499-75914-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v5 20/20] ovn-performance.at: Test port group incremental processing. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org Add tests to make sure port group change doesn't trigger recomputing. Signed-off-by: Han Zhou --- tests/ovn-performance.at | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/tests/ovn-performance.at b/tests/ovn-performance.at index 671dd6e..6a213eb 100644 --- a/tests/ovn-performance.at +++ b/tests/ovn-performance.at @@ -279,6 +279,12 @@ for i in 1 2; do ) done +get_lsp_uuid () { + ovn-nbctl lsp-list ls${1#lp} | grep $1 | awk '{ print $1 }' +} + +pg_ports= + for i in 1 2; do j=$((i%2 + 1)) as=as$i @@ -291,6 +297,9 @@ for i in 1 2; do [hv1 hv2], [lflow_run], [ovn-nbctl --wait=hv lsp-add $ls $lp] ) + + pg_ports="$pg_port `get_lsp_uuid $lp`" + OVN_CONTROLLER_EXPECT_NO_HIT( [hv1 hv2], [lflow_run], [ovn-nbctl --wait=hv lsp-set-addresses $lp "dynamic"] @@ -341,12 +350,6 @@ for i in 1 2; do ls=ls$i lp=lp$i - # Delete port $lp - OVN_CONTROLLER_EXPECT_HIT_COND( - [hv$i hv$j], [lflow_run], [>0 =0], - [ovn-nbctl --wait=hv lsp-del $lp] - ) - # Delete ACLs for port $lp OVN_CONTROLLER_EXPECT_NO_HIT( [hv1 hv2], [lflow_run], @@ -368,6 +371,34 @@ for i in 1 2; do ) done +OVN_CONTROLLER_EXPECT_NO_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl --wait=hv create Port_Group name=pg1 ports=\"$pg_ports\"] +) + +# Add ACLs for port group pg1 +OVN_CONTROLLER_EXPECT_NO_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl --wait=hv acl-add pg1 to-lport 1001 'outport == @pg1 && ip4.src == $pg1_ip4' allow] +) + +for i in 1 2; do + j=$((i%2 + 1)) + lp=lp$i + + # Delete port $lp + OVN_CONTROLLER_EXPECT_HIT_COND( + [hv$i hv$j], [lflow_run], [>0 =0], + [ovn-nbctl --wait=hv lsp-del $lp] + ) +done + +# Delete port group pg1 +OVN_CONTROLLER_EXPECT_NO_HIT( + [hv1 hv2], [lflow_run], + [ovn-nbctl --wait=hv destroy Port_Group pg1] +) + for i in 1 2; do ls=ls$i