From patchwork Thu May 12 09:04:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xavier Simonart X-Patchwork-Id: 1630019 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=fixRrnli; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KzQnz2XPWz9sG2 for ; Thu, 12 May 2022 19:04:38 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id BA455419C4; Thu, 12 May 2022 09:04:36 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id su2zat8QpEV4; Thu, 12 May 2022 09:04:34 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp4.osuosl.org (Postfix) with ESMTPS id 291BF4030F; Thu, 12 May 2022 09:04:33 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id DB993C0039; Thu, 12 May 2022 09:04:32 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 05156C002D for ; Thu, 12 May 2022 09:04:32 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id E4D604030F for ; Thu, 12 May 2022 09:04:31 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id zZD-cGuJxUKq for ; Thu, 12 May 2022 09:04:29 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by smtp4.osuosl.org (Postfix) with ESMTPS id 90A66416A3 for ; Thu, 12 May 2022 09:04:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1652346268; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=owwkCVcgn/fkAkxyTLo9bmA2EcHkrX/Uw4ggDIeI3BA=; b=fixRrnliIc0KmAP/+dPeAF2taftJF/qyOp4E21z05/cZsgbkNmBUrUqpdQdPmWW29a026V bdhfbi3z96VC41ir3+GkgByKg4dDWTkUi/4/Q0ZOoU6IE+p0XmJ3MizN1HcdQbK4/0OqQF +b9wXBSNxP8pqj75uiXQTWmNtgnQTVQ= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-117-yX36sYa8OgqSnA4HHzU8yg-1; Thu, 12 May 2022 05:04:27 -0400 X-MC-Unique: yX36sYa8OgqSnA4HHzU8yg-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id D6425803CB8 for ; Thu, 12 May 2022 09:04:26 +0000 (UTC) Received: from wsfd-netdev90.ntdv.lab.eng.bos.redhat.com (wsfd-netdev90.ntdv.lab.eng.bos.redhat.com [10.19.188.196]) by smtp.corp.redhat.com (Postfix) with ESMTP id B6D25400E400; Thu, 12 May 2022 09:04:26 +0000 (UTC) From: Xavier Simonart To: xsimonar@redhat.com, dev@openvswitch.org Date: Thu, 12 May 2022 05:04:25 -0400 Message-Id: <20220512090425.500011-1-xsimonar@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.11.54.2 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=xsimonar@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH ovn] controller: avoid recomputes triggered by SBDB Port_Binding updates. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" When VIF ports are claimed on a chassis, SBDB Port_Binding table is updated. If the SBDB IDL is still is read-only ("in transaction") when such a update is required, the update is not possible and recompute is triggered through I+P failure. This situation can happen: - after updating Port_Binding->chassis to SBDB for one port, in a following iteration, ovn-controller handles Interface:external_ids:ovn-installed (for the same port) while SBDB is still read-only. - after updating Port_Binding->chassis to SBDB for one port, in a following iteration, ovn-controller updates Port_Binding->chassis for another port, while SBDB is still read-only. This patch prevent the recompute, by having the if-status module updating the Port_Binding chassis (if needed), when possible. This does not delay Port_Binding chassis update compared to before this patch: Port_Binding chassis will be updated as soon as SBDB is again writable, as it was the case, through a recompute, before this patch. Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2059253 Signed-off-by: Xavier Simonart --- controller/binding.c | 124 ++++++++++++++++++++++++++---------- controller/binding.h | 9 ++- controller/if-status.c | 31 +++++++-- controller/if-status.h | 6 +- controller/ovn-controller.c | 6 +- tests/ovn.at | 55 +++++++++++++++- 6 files changed, 184 insertions(+), 47 deletions(-) diff --git a/controller/binding.c b/controller/binding.c index e5ba56b25..d917d8775 100644 --- a/controller/binding.c +++ b/controller/binding.c @@ -657,11 +657,15 @@ local_binding_get_lport_ofport(const struct shash *local_bindings, } bool -local_binding_is_up(struct shash *local_bindings, const char *pb_name) +local_binding_is_up(struct shash *local_bindings, const char *pb_name, + const struct sbrec_chassis *chassis_rec) { struct local_binding *lbinding = local_binding_find(local_bindings, pb_name); struct binding_lport *b_lport = local_binding_get_primary_lport(lbinding); + if (b_lport && b_lport->pb->chassis != chassis_rec) { + return false; + } if (lbinding && b_lport && lbinding->iface) { if (b_lport->pb->n_up && !b_lport->pb->up[0]) { return false; @@ -673,13 +677,23 @@ local_binding_is_up(struct shash *local_bindings, const char *pb_name) } bool -local_binding_is_down(struct shash *local_bindings, const char *pb_name) +local_binding_is_down(struct shash *local_bindings, const char *pb_name, + const struct sbrec_chassis *chassis_rec) { struct local_binding *lbinding = local_binding_find(local_bindings, pb_name); struct binding_lport *b_lport = local_binding_get_primary_lport(lbinding); + if (b_lport) { + if (b_lport->pb->chassis == chassis_rec) { + return false; + } else if (b_lport->pb->chassis) { + VLOG_DBG("lport %s already claimed by other chassis", + b_lport->pb->logical_port); + } + } + if (!lbinding) { return true; } @@ -894,6 +908,48 @@ get_lport_type_str(enum en_lport_type lport_type) OVS_NOT_REACHED(); } +static void set_pb_chassis_in_sbrec(const struct sbrec_port_binding *pb, + const struct sbrec_chassis *chassis_rec) +{ + if (pb->chassis != chassis_rec) { + if (pb->chassis) { + VLOG_INFO("Changing chassis for lport %s from %s to %s.", + pb->logical_port, pb->chassis->name, + chassis_rec->name); + } else { + VLOG_INFO("Claiming lport %s for this chassis.", pb->logical_port); + } + for (int i = 0; i < pb->n_mac; i++) { + VLOG_INFO("%s: Claiming %s", pb->logical_port, pb->mac[i]); + } + sbrec_port_binding_set_chassis(pb, chassis_rec); + } +} + +static void clear_pb_chassis_in_sbrec(const struct sbrec_port_binding *pb) +{ + if (pb->chassis) { + sbrec_port_binding_set_chassis(pb, NULL); + } +} + +void +local_binding_set_pb(struct shash *local_bindings, const char *pb_name, + const struct sbrec_chassis *chassis_rec) +{ + struct local_binding *lbinding = + local_binding_find(local_bindings, pb_name); + struct binding_lport *b_lport = local_binding_get_primary_lport(lbinding); + + if (b_lport) { + if (chassis_rec) { + set_pb_chassis_in_sbrec(b_lport->pb, chassis_rec); + } else { + clear_pb_chassis_in_sbrec(b_lport->pb); + } + } +} + /* For newly claimed ports, if 'notify_up' is 'false': * - set the 'pb.up' field to true if 'pb' has no 'parent_pb'. * - set the 'pb.up' field to true if 'parent_pb.up' is 'true' (e.g., for @@ -906,23 +962,37 @@ get_lport_type_str(enum en_lport_type lport_type) * it's explicitly set to 'false'. * This is to ensure compatibility with older versions of ovn-northd. */ -static void +static bool claimed_lport_set_up(const struct sbrec_port_binding *pb, const struct sbrec_port_binding *parent_pb, const struct sbrec_chassis *chassis_rec, - bool notify_up, struct if_status_mgr *if_mgr) + bool notify_up, struct if_status_mgr *if_mgr, + bool sb_readonly) { + if (!notify_up) { bool up = true; if (!parent_pb || (parent_pb->n_up && parent_pb->up[0])) { - sbrec_port_binding_set_up(pb, &up, 1); + if (!sb_readonly) { + sbrec_port_binding_set_up(pb, &up, 1); + } else if (pb->n_up && !pb->up[0]) { + return false; + } } - return; + if (sb_readonly && (pb->chassis != chassis_rec)) { + /* Handle the cases where if_status_mgr does not claim the + * interface.In those cases, if we do not set pb->chassis in sb + * now (as readonly), we might not do it later ... + */ + return false; + } + return true; } if (pb->chassis != chassis_rec || (pb->n_up && !pb->up[0])) { if_status_mgr_claim_iface(if_mgr, pb->logical_port); } + return true; } /* Returns false if lport is not claimed due to 'sb_readonly'. @@ -937,27 +1007,15 @@ claim_lport(const struct sbrec_port_binding *pb, struct hmap *tracked_datapaths, struct if_status_mgr *if_mgr) { - if (!sb_readonly) { - claimed_lport_set_up(pb, parent_pb, chassis_rec, notify_up, if_mgr); - } + if (!claimed_lport_set_up(pb, parent_pb, chassis_rec, notify_up, + if_mgr, sb_readonly)) { + return false; + } if (pb->chassis != chassis_rec) { - if (sb_readonly) { - return false; - } - - if (pb->chassis) { - VLOG_INFO("Changing chassis for lport %s from %s to %s.", - pb->logical_port, pb->chassis->name, - chassis_rec->name); - } else { - VLOG_INFO("Claiming lport %s for this chassis.", pb->logical_port); + if (!sb_readonly) { + set_pb_chassis_in_sbrec(pb, chassis_rec); } - for (int i = 0; i < pb->n_mac; i++) { - VLOG_INFO("%s: Claiming %s", pb->logical_port, pb->mac[i]); - } - - sbrec_port_binding_set_chassis(pb, chassis_rec); if (tracked_datapaths) { update_lport_tracking(pb, tracked_datapaths, true); @@ -974,7 +1032,6 @@ claim_lport(const struct sbrec_port_binding *pb, } sbrec_port_binding_set_encap(pb, encap_rec); } - return true; } @@ -986,7 +1043,8 @@ claim_lport(const struct sbrec_port_binding *pb, * Caller should make sure that this is the case. */ static bool -release_lport_(const struct sbrec_port_binding *pb, bool sb_readonly) +release_lport_(const struct sbrec_port_binding *pb, bool sb_readonly, + struct if_status_mgr *if_mgr) { if (pb->encap) { if (sb_readonly) { @@ -995,11 +1053,13 @@ release_lport_(const struct sbrec_port_binding *pb, bool sb_readonly) sbrec_port_binding_set_encap(pb, NULL); } + /* if sb readonly, pb->chassis unset through if-status if present */ if (pb->chassis) { - if (sb_readonly) { + if (!sb_readonly) { + sbrec_port_binding_set_chassis(pb, NULL); + } else if (!if_status_mgr_iface_is_present(if_mgr, pb->logical_port)) { return false; } - sbrec_port_binding_set_chassis(pb, NULL); } if (pb->virtual_parent) { @@ -1009,7 +1069,8 @@ release_lport_(const struct sbrec_port_binding *pb, bool sb_readonly) sbrec_port_binding_set_virtual_parent(pb, NULL); } - VLOG_INFO("Releasing lport %s from this chassis.", pb->logical_port); + VLOG_INFO("Releasing lport %s from this chassis (sb_readonly=%d)", + pb->logical_port, sb_readonly); return true; } @@ -1017,7 +1078,7 @@ static bool release_lport(const struct sbrec_port_binding *pb, bool sb_readonly, struct hmap *tracked_datapaths, struct if_status_mgr *if_mgr) { - if (!release_lport_(pb, sb_readonly)) { + if (!release_lport_(pb, sb_readonly, if_mgr)) { return false; } @@ -1342,10 +1403,9 @@ consider_localport(const struct sbrec_port_binding *pb, /* If the port binding is claimed, then release it as localport is claimed * by any ovn-controller. */ if (pb->chassis == b_ctx_in->chassis_rec) { - if (!release_lport_(pb, !b_ctx_in->ovnsb_idl_txn)) { + if (!release_lport_(pb, !b_ctx_in->ovnsb_idl_txn, b_ctx_out->if_mgr)) { return false; } - remove_related_lport(pb, b_ctx_out); } diff --git a/controller/binding.h b/controller/binding.h index 430a8d9b1..45202a321 100644 --- a/controller/binding.h +++ b/controller/binding.h @@ -151,14 +151,17 @@ const struct sbrec_port_binding *local_binding_get_primary_pb( ofp_port_t local_binding_get_lport_ofport(const struct shash *local_bindings, const char *pb_name); -bool local_binding_is_up(struct shash *local_bindings, const char *pb_name); -bool local_binding_is_down(struct shash *local_bindings, const char *pb_name); +bool local_binding_is_up(struct shash *local_bindings, const char *pb_name, + const struct sbrec_chassis *); +bool local_binding_is_down(struct shash *local_bindings, const char *pb_name, + const struct sbrec_chassis *); void local_binding_set_up(struct shash *local_bindings, const char *pb_name, const char *ts_now_str, bool sb_readonly, bool ovs_readonly); void local_binding_set_down(struct shash *local_bindings, const char *pb_name, bool sb_readonly, bool ovs_readonly); - +void local_binding_set_pb(struct shash *local_bindings, const char *pb_name, + const struct sbrec_chassis *chassis_rec); void binding_register_ovs_idl(struct ovsdb_idl *); void binding_run(struct binding_ctx_in *, struct binding_ctx_out *); bool binding_cleanup(struct ovsdb_idl_txn *ovnsb_idl_txn, diff --git a/controller/if-status.c b/controller/if-status.c index dbdf8b66f..e36df22a0 100644 --- a/controller/if-status.c +++ b/controller/if-status.c @@ -115,6 +115,7 @@ static void ovs_iface_set_state(struct if_status_mgr *, struct ovs_iface *, static void if_status_mgr_update_bindings( struct if_status_mgr *mgr, struct local_binding_data *binding_data, + const struct sbrec_chassis *chassis_rec, bool sb_readonly, bool ovs_readonly); struct if_status_mgr * @@ -181,6 +182,13 @@ if_status_mgr_claim_iface(struct if_status_mgr *mgr, const char *iface_id) } } +bool +if_status_mgr_iface_is_present(struct if_status_mgr *mgr, const char *iface_id) +{ + struct ovs_iface *iface = shash_find_data(&mgr->ifaces, iface_id); + return (!!iface); +} + void if_status_mgr_release_iface(struct if_status_mgr *mgr, const char *iface_id) { @@ -247,7 +255,8 @@ if_status_mgr_delete_iface(struct if_status_mgr *mgr, const char *iface_id) void if_status_mgr_update(struct if_status_mgr *mgr, - struct local_binding_data *binding_data) + struct local_binding_data *binding_data, + const struct sbrec_chassis *chassis_rec) { if (!binding_data) { return; @@ -262,7 +271,7 @@ if_status_mgr_update(struct if_status_mgr *mgr, HMAPX_FOR_EACH_SAFE (node, &mgr->ifaces_per_state[OIF_MARK_UP]) { struct ovs_iface *iface = node->data; - if (local_binding_is_up(bindings, iface->id)) { + if (local_binding_is_up(bindings, iface->id, chassis_rec)) { ovs_iface_set_state(mgr, iface, OIF_INSTALLED); } } @@ -273,7 +282,7 @@ if_status_mgr_update(struct if_status_mgr *mgr, HMAPX_FOR_EACH_SAFE (node, &mgr->ifaces_per_state[OIF_MARK_DOWN]) { struct ovs_iface *iface = node->data; - if (local_binding_is_down(bindings, iface->id)) { + if (local_binding_is_down(bindings, iface->id, chassis_rec)) { ovs_iface_destroy(mgr, iface); } } @@ -306,6 +315,7 @@ if_status_mgr_update(struct if_status_mgr *mgr, void if_status_mgr_run(struct if_status_mgr *mgr, struct local_binding_data *binding_data, + const struct sbrec_chassis *chassis_rec, bool sb_readonly, bool ovs_readonly) { struct ofctrl_acked_seqnos *acked_seqnos = @@ -328,8 +338,8 @@ if_status_mgr_run(struct if_status_mgr *mgr, ofctrl_acked_seqnos_destroy(acked_seqnos); /* Update binding states. */ - if_status_mgr_update_bindings(mgr, binding_data, sb_readonly, - ovs_readonly); + if_status_mgr_update_bindings(mgr, binding_data, chassis_rec, + sb_readonly, ovs_readonly); } static void @@ -390,6 +400,7 @@ ovs_iface_set_state(struct if_status_mgr *mgr, struct ovs_iface *iface, static void if_status_mgr_update_bindings(struct if_status_mgr *mgr, struct local_binding_data *binding_data, + const struct sbrec_chassis *chassis_rec, bool sb_readonly, bool ovs_readonly) { if (!binding_data) { @@ -404,6 +415,9 @@ if_status_mgr_update_bindings(struct if_status_mgr *mgr, */ HMAPX_FOR_EACH (node, &mgr->ifaces_per_state[OIF_INSTALL_FLOWS]) { struct ovs_iface *iface = node->data; + if (!sb_readonly) { + local_binding_set_pb(bindings, iface->id, chassis_rec); + } local_binding_set_down(bindings, iface->id, sb_readonly, ovs_readonly); } @@ -415,7 +429,9 @@ if_status_mgr_update_bindings(struct if_status_mgr *mgr, char *ts_now_str = xasprintf("%lld", time_wall_msec()); HMAPX_FOR_EACH (node, &mgr->ifaces_per_state[OIF_MARK_UP]) { struct ovs_iface *iface = node->data; - + if (!sb_readonly) { + local_binding_set_pb(bindings, iface->id, chassis_rec); + } local_binding_set_up(bindings, iface->id, ts_now_str, sb_readonly, ovs_readonly); } @@ -426,6 +442,9 @@ if_status_mgr_update_bindings(struct if_status_mgr *mgr, */ HMAPX_FOR_EACH (node, &mgr->ifaces_per_state[OIF_MARK_DOWN]) { struct ovs_iface *iface = node->data; + if (!sb_readonly) { + local_binding_set_pb(bindings, iface->id, NULL); + } local_binding_set_down(bindings, iface->id, sb_readonly, ovs_readonly); } diff --git a/controller/if-status.h b/controller/if-status.h index ff4aa760e..2c55eb18e 100644 --- a/controller/if-status.h +++ b/controller/if-status.h @@ -31,10 +31,14 @@ void if_status_mgr_claim_iface(struct if_status_mgr *, const char *iface_id); void if_status_mgr_release_iface(struct if_status_mgr *, const char *iface_id); void if_status_mgr_delete_iface(struct if_status_mgr *, const char *iface_id); -void if_status_mgr_update(struct if_status_mgr *, struct local_binding_data *); +void if_status_mgr_update(struct if_status_mgr *, struct local_binding_data *, + const struct sbrec_chassis *chassis); void if_status_mgr_run(struct if_status_mgr *mgr, struct local_binding_data *, + const struct sbrec_chassis *chassis, bool sb_readonly, bool ovs_readonly); void if_status_mgr_get_memory_usage(struct if_status_mgr *mgr, struct simap *usage); +bool if_status_mgr_iface_is_present(struct if_status_mgr *mgr, + const char *iface_id); # endif /* controller/if-status.h */ diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c index 5a6274eb2..994aebdfb 100644 --- a/controller/ovn-controller.c +++ b/controller/ovn-controller.c @@ -3912,7 +3912,7 @@ main(int argc, char *argv[]) runtime_data ? &runtime_data->lbinding_data : NULL; stopwatch_start(IF_STATUS_MGR_UPDATE_STOPWATCH_NAME, time_msec()); - if_status_mgr_update(if_mgr, binding_data); + if_status_mgr_update(if_mgr, binding_data, chassis); stopwatch_stop(IF_STATUS_MGR_UPDATE_STOPWATCH_NAME, time_msec()); @@ -3938,8 +3938,8 @@ main(int argc, char *argv[]) time_msec()); stopwatch_start(IF_STATUS_MGR_RUN_STOPWATCH_NAME, time_msec()); - if_status_mgr_run(if_mgr, binding_data, !ovnsb_idl_txn, - !ovs_idl_txn); + if_status_mgr_run(if_mgr, binding_data, chassis, + !ovnsb_idl_txn, !ovs_idl_txn); stopwatch_stop(IF_STATUS_MGR_RUN_STOPWATCH_NAME, time_msec()); } diff --git a/tests/ovn.at b/tests/ovn.at index 6a0a169c1..403fbc85f 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -13934,6 +13934,7 @@ ovn_attach n1 br-phys 192.168.0.11 ovs-vsctl -- add-port br-int hv1-vif0 -- \ set Interface hv1-vif0 ofport-request=1 + sim_add hv2 as hv2 ovs-vsctl add-br br-phys @@ -13983,7 +13984,10 @@ AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], echo "verifying that lsp0 binding moves when requested-chassis is changed" ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2 -OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)]) + +# We might see multiple "Releasing lport ...", when sb is read only +OVS_WAIT_UNTIL([test 1 -le $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)]) + wait_column "$hv2_uuid" Port_Binding chassis logical_port=lsp0 # (6) Chassis hv2 should add flows and hv1 should not. @@ -14029,7 +14033,7 @@ AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ig AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore]) check ovn-nbctl --wait=hv lsp-set-options lsp0 requested-chassis=non-existant-chassis -OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)]) +OVS_WAIT_UNTIL([test 1 -le $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)]) check ovn-nbctl --wait=hv sync wait_column '' Port_Binding chasssi logical_port=lsp0 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], []) @@ -30595,3 +30599,50 @@ test_mac_binding_flows hv2 00\:00\:00\:00\:10\:10 1 OVN_CLEANUP([hv1], [hv2]) AT_CLEANUP ]) + +OVN_FOR_EACH_NORTHD([ +AT_SETUP([recomputes]) +ovn_start + +# Add chassis +net_add n1 +sim_add hv1 +as hv1 +ovs-vsctl add-br br-phys +ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys +ovn_attach n1 br-phys 192.168.0.1 + +add_switch_ports() { + for port in $(seq $1 $2); do + logical_switch_port=lsp${port} + check ovn-nbctl lsp-add ls1 $logical_switch_port + check ovn-nbctl lsp-set-addresses $logical_switch_port dynamic + + as hv1 ovs-vsctl \ + -- add-port br-int vif${port} \ + -- set Interface vif${port} external_ids:iface-id=$logical_switch_port + done + + check ovn-nbctl --wait=hv sync + AT_CHECK([test $(ovn-appctl -t ovn-controller coverage/read-counter lflow_run) == $lflow_run]) +} + +check ovn-nbctl ls-add ls1 +check ovn-nbctl set Logical_Switch ls1 other_config:subnet=10.1.0.0/16 +check ovn-nbctl set Logical_Switch ls1 other_config:exclude_ips=10.1.255.254 + +check ovn-nbctl lr-add lr1 +check ovn-nbctl lsp-add ls1 lsp0 -- set Logical_Switch_Port lsp0 type=router options:router-port=lrp0 addresses=dynamic +check ovn-nbctl lrp-add lr1 lrp0 "f0:00:00:01:00:01" 10.1.255.254/16 +check ovn-nbctl lr-nat-add lr1 snat 10.2.0.1 10.1.0.0/16 + +check ovn-nbctl --wait=hv sync +lflow_run=$(ovn-appctl -t ovn-controller coverage/read-counter lflow_run) + +add_switch_ports 1 50 +add_switch_ports 51 100 +add_switch_ports 101 150 + +OVN_CLEANUP([hv1]) +AT_CLEANUP +])