From f6dc4f36adf7da72a73228c1b4acf8f8b362e81c Mon Sep 17 00:00:00 2001 From: Marco Sinhoreli Date: Mon, 4 May 2026 13:32:26 +0200 Subject: [PATCH] NE: persist OVN broadcast type and URI on Network for vif.binding=lswitch Companion to the NIC-level URI override -- when an extension declares vif.binding=lswitch, the Network row itself should advertise ``broadcast_domain_type=Lswitch`` and ``broadcast_uri=ovn://cs-net-`` so listNetworks / details views are consistent with what the OVN control plane represents. Without this hook the GuestNetworkGuru still allocated a VLAN at design time, which leaks back into the UI: VLAN/VNI: 138 Broadcast URI: vlan://138 Apply the override on a successful ``implement-network`` script return in NetworkExtensionElement.implement(). The VLAN that the guru allocated stays as a ghost in op_dc_vnet_alloc -- it is never used on the wire because the VIF attaches to br-int and traffic flows through OVN's logical pipeline over geneve. Releasing the VLAN back to the pool would require intercepting the design phase and is out of scope for this hook. Verified end-to-end: i-2-27-VM on network 216 now lists networks.broadcast_uri = ovn://cs-net-216 networks.broadcast_domain_type = Lswitch nics.broadcast_uri = ovn://cs-net-216 nics.isolation_uri = ovn://cs-net-216 The OVN NB LSP / OVS iface-id / OVN SB Port_Binding remain bound, as before. --- .../network/NetworkExtensionElement.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/network/NetworkExtensionElement.java b/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/network/NetworkExtensionElement.java index d10c6b74cb1..5b26d3fca4c 100644 --- a/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/network/NetworkExtensionElement.java +++ b/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/network/NetworkExtensionElement.java @@ -52,6 +52,8 @@ import com.cloud.network.Network.Service; import com.cloud.network.NetworkModel; import com.cloud.network.Networks; import com.cloud.network.dao.NetworkDetailVO; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.network.PhysicalNetworkServiceProvider; @@ -245,6 +247,8 @@ public class NetworkExtensionElement extends AdapterBase implements @Inject private ExtensionDetailsDao extensionDetailsDao; @Inject + private NetworkDao networkDao; + @Inject private DataCenterDao dataCenterDao; @Inject private VlanDao vlanDao; @@ -311,6 +315,7 @@ public class NetworkExtensionElement extends AdapterBase implements copy.ipAddressManager = this.ipAddressManager; copy.physicalNetworkDao = this.physicalNetworkDao; copy.extensionDetailsDao = this.extensionDetailsDao; + copy.networkDao = this.networkDao; copy.dataCenterDao = this.dataCenterDao; copy.vlanDao = this.vlanDao; copy.guestOSCategoryDao = this.guestOSCategoryDao; @@ -466,6 +471,27 @@ public class NetworkExtensionElement extends AdapterBase implements return false; } + // When the extension declares vif.binding=lswitch, also update the + // Network row itself so listNetworks / DB queries advertise the + // OVN-flavoured identifier instead of the cosmetic VLAN URI the + // GuestNetworkGuru allocated at design-time. Format follows the + // legacy ovn-plugin convention: ``ovn://cs-net-``. + if (isLswitchVifBinding(network)) { + try { + NetworkVO networkVo = networkDao.findById(network.getId()); + if (networkVo != null) { + java.net.URI ovnUri = java.net.URI.create("ovn://cs-net-" + network.getId()); + networkVo.setBroadcastDomainType(Networks.BroadcastDomainType.Lswitch); + networkVo.setBroadcastUri(ovnUri); + networkDao.update(networkVo.getId(), networkVo); + logger.debug("implement: applied Lswitch broadcast type and ovn:// URI to network {} per extension vif.binding hint", + network.getId()); + } + } catch (Exception e) { + logger.warn("Failed to persist OVN URI on network {}: {}", network.getId(), e.getMessage()); + } + } + // Step 3: Configure source NAT for both VPC and non-VPC networks for // compatibility (other network-element providers may also implement VPC tiers). // When this is a VPC tier, the script's assign-ip does nothing for source-nat