From a455e0f35b911a2d8fc8af57bd5eeb22c446531a Mon Sep 17 00:00:00 2001 From: "shixin.ruan" Date: Mon, 18 May 2026 11:00:19 +0800 Subject: [PATCH 1/6] [network]: add attach skip hook ZCF-3703: allow ZNS to ignore Flat DHCP attach. Change-Id: If8929ee4cc111825b42b688678bca81b3f08eed5 --- ...APIAttachNetworkServiceToL3NetworkMsg.java | 9 ++++++++ .../NetworkServiceAttachExtensionPoint.java | 5 +++++ .../org/zstack/network/l3/L3BasicNetwork.java | 7 ++++++ .../service/NetworkServiceApiInterceptor.java | 22 ++++++++++++++++--- 4 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 header/src/main/java/org/zstack/header/network/service/NetworkServiceAttachExtensionPoint.java diff --git a/header/src/main/java/org/zstack/header/network/service/APIAttachNetworkServiceToL3NetworkMsg.java b/header/src/main/java/org/zstack/header/network/service/APIAttachNetworkServiceToL3NetworkMsg.java index c51ba7f5423..0eacdd3e6e1 100755 --- a/header/src/main/java/org/zstack/header/network/service/APIAttachNetworkServiceToL3NetworkMsg.java +++ b/header/src/main/java/org/zstack/header/network/service/APIAttachNetworkServiceToL3NetworkMsg.java @@ -66,6 +66,7 @@ public class APIAttachNetworkServiceToL3NetworkMsg extends APIMessage implements */ @APIParam private Map> networkServices; + private transient boolean skipAttach; @Override public String getL3NetworkUuid() { @@ -83,6 +84,14 @@ public void setNetworkServices(Map> networkServices) { public void setL3NetworkUuid(String l3NetworkUuid) { this.l3NetworkUuid = l3NetworkUuid; } + + public boolean isSkipAttach() { + return skipAttach; + } + + public void setSkipAttach(boolean skipAttach) { + this.skipAttach = skipAttach; + } public static APIAttachNetworkServiceToL3NetworkMsg __example__() { APIAttachNetworkServiceToL3NetworkMsg msg = new APIAttachNetworkServiceToL3NetworkMsg(); diff --git a/header/src/main/java/org/zstack/header/network/service/NetworkServiceAttachExtensionPoint.java b/header/src/main/java/org/zstack/header/network/service/NetworkServiceAttachExtensionPoint.java new file mode 100644 index 00000000000..1b61aac5fad --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/service/NetworkServiceAttachExtensionPoint.java @@ -0,0 +1,5 @@ +package org.zstack.header.network.service; + +public interface NetworkServiceAttachExtensionPoint { + boolean skipAttachNetworkService(APIAttachNetworkServiceToL3NetworkMsg msg); +} diff --git a/network/src/main/java/org/zstack/network/l3/L3BasicNetwork.java b/network/src/main/java/org/zstack/network/l3/L3BasicNetwork.java index 1e4f046423d..43849b41e34 100755 --- a/network/src/main/java/org/zstack/network/l3/L3BasicNetwork.java +++ b/network/src/main/java/org/zstack/network/l3/L3BasicNetwork.java @@ -1560,6 +1560,13 @@ public void fail(ErrorCode errorCode) { private void handle(APIAttachNetworkServiceToL3NetworkMsg msg) { APIAttachNetworkServiceToL3NetworkEvent evt = new APIAttachNetworkServiceToL3NetworkEvent(msg.getId()); + if (msg.isSkipAttach()) { + self = dbf.reload(self); + evt.setInventory(L3NetworkInventory.valueOf(self)); + bus.publish(evt); + return; + } + AttachNetworkServiceToL3Msg amsg = new AttachNetworkServiceToL3Msg(); amsg.setL3NetworkUuid(msg.getL3NetworkUuid()); amsg.setNetworkServices(msg.getNetworkServices()); diff --git a/network/src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java b/network/src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java index dad5d87781a..6ff551fc9ea 100755 --- a/network/src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java +++ b/network/src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java @@ -1,6 +1,7 @@ package org.zstack.network.service; import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.SimpleQuery; import org.zstack.core.db.SimpleQuery.Op; @@ -29,16 +30,22 @@ /** */ -public class NetworkServiceApiInterceptor implements ApiMessageInterceptor { - private final static CLogger logger = Utils.getLogger(NetworkServiceApiInterceptor.class); - @Autowired +public class NetworkServiceApiInterceptor implements ApiMessageInterceptor { + private final static CLogger logger = Utils.getLogger(NetworkServiceApiInterceptor.class); + @Autowired private DatabaseFacade dbf; + @Autowired + private PluginRegistry pluginRgty; @Override public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionException { if (msg instanceof APIAttachNetworkServiceToL3NetworkMsg) { APIAttachNetworkServiceToL3NetworkMsg attachMsg = (APIAttachNetworkServiceToL3NetworkMsg)msg; attachMsg.setNetworkServices(convertNetworkProviderTypeToUuid(attachMsg.getNetworkServices())); + if (skipAttachNetworkService(attachMsg)) { + attachMsg.setSkipAttach(true); + return msg; + } validate(attachMsg); } else if (msg instanceof APIDetachNetworkServiceFromL3NetworkMsg) { APIDetachNetworkServiceFromL3NetworkMsg detachMsg = (APIDetachNetworkServiceFromL3NetworkMsg)msg; @@ -59,6 +66,15 @@ public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionExcepti return msg; } + private boolean skipAttachNetworkService(APIAttachNetworkServiceToL3NetworkMsg msg) { + for (NetworkServiceAttachExtensionPoint ext : pluginRgty.getExtensionList(NetworkServiceAttachExtensionPoint.class)) { + if (ext.skipAttachNetworkService(msg)) { + return true; + } + } + return false; + } + private void validate(APIAttachNetworkServiceToL3NetworkMsg msg) { if (msg.getNetworkServices().isEmpty()) { throw new ApiMessageInterceptionException(argerr(ORG_ZSTACK_NETWORK_SERVICE_10006, "networkServices cannot be empty")); From fd6da83bcaf202ebf57279d495601eb4e2eb95ef Mon Sep 17 00:00:00 2001 From: "shixin.ruan" Date: Mon, 18 May 2026 11:38:50 +0800 Subject: [PATCH 2/6] [network]: trim attach service input Normalize attach network service provider keys and service names before provider conversion and skip extension checks. Hide the internal skipAttach flag from API surface. Resolves: ZCF-3703 Change-Id: Id6ff18d0bf5e86937c50a82721249055d3f76ade --- ...APIAttachNetworkServiceToL3NetworkMsg.java | 2 + .../service/NetworkServiceProviderType.java | 9 +++++ .../service/NetworkServiceApiInterceptor.java | 39 ++++++++++++++++++- .../network/service/flat/FlatDhcpBackend.java | 18 ++++++++- 4 files changed, 64 insertions(+), 4 deletions(-) diff --git a/header/src/main/java/org/zstack/header/network/service/APIAttachNetworkServiceToL3NetworkMsg.java b/header/src/main/java/org/zstack/header/network/service/APIAttachNetworkServiceToL3NetworkMsg.java index 0eacdd3e6e1..1753638d0d1 100755 --- a/header/src/main/java/org/zstack/header/network/service/APIAttachNetworkServiceToL3NetworkMsg.java +++ b/header/src/main/java/org/zstack/header/network/service/APIAttachNetworkServiceToL3NetworkMsg.java @@ -8,6 +8,7 @@ import org.zstack.header.network.l3.L3NetworkConstant; import org.zstack.header.network.l3.L3NetworkMessage; import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.rest.APINoSee; import org.zstack.header.rest.RestRequest; import java.util.*; @@ -66,6 +67,7 @@ public class APIAttachNetworkServiceToL3NetworkMsg extends APIMessage implements */ @APIParam private Map> networkServices; + @APINoSee private transient boolean skipAttach; @Override diff --git a/header/src/main/java/org/zstack/header/network/service/NetworkServiceProviderType.java b/header/src/main/java/org/zstack/header/network/service/NetworkServiceProviderType.java index 852bd09c401..a5ae83ce72f 100755 --- a/header/src/main/java/org/zstack/header/network/service/NetworkServiceProviderType.java +++ b/header/src/main/java/org/zstack/header/network/service/NetworkServiceProviderType.java @@ -10,6 +10,7 @@ public class NetworkServiceProviderType { private final String typeName; private boolean createDhcpNameSpace = true; private boolean allocateDhcpServerIp = true; + private boolean allocateDhcpv6ServerIp = true; public NetworkServiceProviderType(String typeName) { this.typeName = typeName; @@ -55,6 +56,14 @@ public void setAllocateDhcpServerIp(boolean allocateDhcpServerIp) { this.allocateDhcpServerIp = allocateDhcpServerIp; } + public boolean isAllocateDhcpv6ServerIp() { + return allocateDhcpv6ServerIp; + } + + public void setAllocateDhcpv6ServerIp(boolean allocateDhcpv6ServerIp) { + this.allocateDhcpv6ServerIp = allocateDhcpv6ServerIp; + } + @Override public int hashCode() { return typeName.hashCode(); diff --git a/network/src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java b/network/src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java index 6ff551fc9ea..9b95e53ee9a 100755 --- a/network/src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java +++ b/network/src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java @@ -173,11 +173,11 @@ public String call(String type) { } private Map> convertNetworkProviderTypeToUuid(Map> map){ - if (map.isEmpty()) { + Map> mapNew = normalizeNetworkServices(map); + if (mapNew.isEmpty()) { throw new ApiMessageInterceptionException(argerr(ORG_ZSTACK_NETWORK_SERVICE_10012, "networkServices cannot be empty")); } - Map> mapNew = new HashMap<>(map); List networkServiceProviderVOs = Q.New(NetworkServiceProviderVO.class).list(); for (NetworkServiceProviderVO vo :networkServiceProviderVOs) { @@ -188,4 +188,39 @@ private Map> convertNetworkProviderTypeToUuid(Map> normalizeNetworkServices(Map> map) { + Map> ret = new LinkedHashMap<>(); + if (map == null) { + return ret; + } + + for (Map.Entry> entry : map.entrySet()) { + if (entry.getKey() == null) { + continue; + } + + String provider = entry.getKey().trim(); + if (provider.isEmpty()) { + continue; + } + + List services = new ArrayList<>(); + if (entry.getValue() != null) { + for (String service : entry.getValue()) { + if (service == null) { + continue; + } + + String normalized = service.trim(); + if (!normalized.isEmpty()) { + services.add(normalized); + } + } + } + + ret.computeIfAbsent(provider, k -> new ArrayList<>()).addAll(services); + } + return ret; + } } diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java index 5823bb2b9ee..db72febcf4d 100755 --- a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java @@ -996,7 +996,7 @@ public static Map getExistingDhcpServerIp(String l3Uuid, int ipV @Deferred private String allocateDhcpIp(String l3Uuid, int ipVersion, boolean allocate_ip, String requiredIp, String excludedIp) { - if (!isAllocateDhcpServerIp(l3Uuid)) { + if (!isAllocateDhcpServerIp(l3Uuid, ipVersion)) { return null; } @@ -1276,6 +1276,17 @@ private boolean isAllocateDhcpServerIp(String l3Uuid) { return type.isAllocateDhcpServerIp(); } + private boolean isAllocateDhcpServerIp(String l3Uuid, int ipVersion) { + String providerType = new NetworkProviderFinder().getNetworkProviderTypeByNetworkServiceType(l3Uuid, NetworkServiceType.DHCP.toString()); + if (providerType == null) { + return false; + } + + NetworkServiceProviderType type = NetworkServiceProviderType.valueOf(providerType); + return type.isAllocateDhcpServerIp() + && (ipVersion != IPv6Constants.IPv6 || type.isAllocateDhcpv6ServerIp()); + } + private boolean isCreateDhcpNameSpace(String l3Uuid) { String providerType = new NetworkProviderFinder().getNetworkProviderTypeByNetworkServiceType(l3Uuid, NetworkServiceType.DHCP.toString()); if (providerType == null) { @@ -2490,7 +2501,10 @@ private void validate(APIDetachNetworkServiceFromL3NetworkMsg msg) { } private void validate(APIChangeL3NetworkDhcpIpAddressMsg msg) { - if (!isAllocateDhcpServerIp(msg.getL3NetworkUuid())) { + if ((msg.getDhcpServerIp() != null && !isAllocateDhcpServerIp(msg.getL3NetworkUuid(), IPv6Constants.IPv4)) + || (msg.getDhcpv6ServerIp() != null && !isAllocateDhcpServerIp(msg.getL3NetworkUuid(), IPv6Constants.IPv6)) + || (msg.getDhcpServerIp() == null && msg.getDhcpv6ServerIp() == null + && !isAllocateDhcpServerIp(msg.getL3NetworkUuid()))) { throw new ApiMessageInterceptionException(argerr(ORG_ZSTACK_NETWORK_SERVICE_FLAT_10044, "could change dhcp server ip, because flat dhcp is not enabled")); } From e3bb9eb5df357df99e81087a0e6d36ff3a222449 Mon Sep 17 00:00:00 2001 From: "shixin.ruan" Date: Mon, 18 May 2026 16:57:46 +0800 Subject: [PATCH 3/6] [network]: pass dhcp system tags to sdn Resolves: ZCF-3703 Change-Id: I8b002e1c0b7e0535df0803a8107e9b4ebbdadf21 --- .../header/network/l3/SdnControllerEnableDHCPMsg.java | 11 +++++++++++ .../org/zstack/network/service/DhcpExtension.java | 1 + 2 files changed, 12 insertions(+) diff --git a/header/src/main/java/org/zstack/header/network/l3/SdnControllerEnableDHCPMsg.java b/header/src/main/java/org/zstack/header/network/l3/SdnControllerEnableDHCPMsg.java index ade67404bd8..c3255f4c0e5 100644 --- a/header/src/main/java/org/zstack/header/network/l3/SdnControllerEnableDHCPMsg.java +++ b/header/src/main/java/org/zstack/header/network/l3/SdnControllerEnableDHCPMsg.java @@ -3,9 +3,12 @@ import org.zstack.header.message.NeedReplyMessage; import org.zstack.header.network.sdncontroller.SdnControllerMessage; +import java.util.List; + public class SdnControllerEnableDHCPMsg extends NeedReplyMessage implements SdnControllerMessage { private String l3NetworkUuid; private String sdnControllerUuid; + private List systemTags; public String getL3NetworkUuid() { return l3NetworkUuid; @@ -23,4 +26,12 @@ public String getSdnControllerUuid() { public void setSdnControllerUuid(String sdnControllerUuid) { this.sdnControllerUuid = sdnControllerUuid; } + + public List getSystemTags() { + return systemTags; + } + + public void setSystemTags(List systemTags) { + this.systemTags = systemTags; + } } diff --git a/network/src/main/java/org/zstack/network/service/DhcpExtension.java b/network/src/main/java/org/zstack/network/service/DhcpExtension.java index 8e37da8b1e9..ff66b997243 100755 --- a/network/src/main/java/org/zstack/network/service/DhcpExtension.java +++ b/network/src/main/java/org/zstack/network/service/DhcpExtension.java @@ -437,6 +437,7 @@ public void enableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType pr SdnControllerEnableDHCPMsg msg = new SdnControllerEnableDHCPMsg(); msg.setL3NetworkUuid(l3VO.getUuid()); msg.setSdnControllerUuid(sdnControllerUuid); + msg.setSystemTags(systemTags); bus.makeTargetServiceIdByResourceUuid(msg, SdnControllerConstant.SERVICE_ID, sdnControllerUuid); bus.send(msg, new CloudBusCallBack(completion) { @Override From 5dc68e1a9d7d03ca29738bf8d8dc9cf090ea17ea Mon Sep 17 00:00:00 2001 From: "shixin.ruan" Date: Mon, 18 May 2026 19:38:49 +0800 Subject: [PATCH 4/6] [zns]: add dhcp error codes Split ZNS DHCP error codes used by premium DHCP paths.\nAdd i18n mappings for the new concrete error templates. Resolves: ZCF-3703 Change-Id: I11bf0fc6df8cf5a5e1ae24af958c5ca3712b4347 --- .../globalErrorCodeMapping/global-error-en_US.json | 8 +++++++- .../globalErrorCodeMapping/global-error-zh_CN.json | 8 +++++++- .../clouderrorcode/CloudOperationsErrorCode.java | 12 ++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/conf/i18n/globalErrorCodeMapping/global-error-en_US.json b/conf/i18n/globalErrorCodeMapping/global-error-en_US.json index df3c4c42bdf..f5828af0310 100644 --- a/conf/i18n/globalErrorCodeMapping/global-error-en_US.json +++ b/conf/i18n/globalErrorCodeMapping/global-error-en_US.json @@ -4734,5 +4734,11 @@ "ORG_ZSTACK_AI_10162": "VM[name:%s, uuid:%s] must be running to mount/unmount model. Current state: %s", "ORG_ZSTACK_AI_10163": "VM[name:%s, uuid:%s] is not running on any host", "ORG_ZSTACK_AI_10164": "Model[name:%s, uuid:%s] is not shared to the account that owns this VM (or to public). Mount requires the model to be accessible under the same sharing rules as the VM.", - "ORG_ZSTACK_AI_10165": "ModelCenter[uuid:%s] not found for Model[name:%s, uuid:%s]" + "ORG_ZSTACK_AI_10165": "ModelCenter[uuid:%s] not found for Model[name:%s, uuid:%s]", + "ORG_ZSTACK_NETWORK_ZNS_10043": "failed to allocate DHCPv4 server IP for ZNS L3[uuid:%s]", + "ORG_ZSTACK_NETWORK_ZNS_10044": "cannot enable DHCP: L3[uuid:%s] has no eligible IpRange (SLAAC excluded)", + "ORG_ZSTACK_NETWORK_ZNS_10045": "cannot enable DHCP: L3[uuid:%s] has no Cloud-reserved DHCPv4 server IP", + "ORG_ZSTACK_NETWORK_ZNS_10046": "DHCP service already exists on segment[uuid:%s] but GET returned empty", + "ORG_ZSTACK_NETWORK_ZNS_10047": "cannot update DHCP: L3[uuid:%s] has no Cloud-reserved DHCPv4 server IP", + "ORG_ZSTACK_NETWORK_ZNS_10048": "failed to allocate DHCPv4 server IP for ZNS L3[uuid:%s]" } diff --git a/conf/i18n/globalErrorCodeMapping/global-error-zh_CN.json b/conf/i18n/globalErrorCodeMapping/global-error-zh_CN.json index 1400aefd860..8e9b89ac4b3 100644 --- a/conf/i18n/globalErrorCodeMapping/global-error-zh_CN.json +++ b/conf/i18n/globalErrorCodeMapping/global-error-zh_CN.json @@ -4741,5 +4741,11 @@ "ORG_ZSTACK_AI_10162": "虚拟机「%s」(UUID: %s) 必须处于运行状态才能挂载/卸载模型,当前状态: %s", "ORG_ZSTACK_AI_10163": "虚拟机「%s」(UUID: %s) 未运行在任何主机上", "ORG_ZSTACK_AI_10164": "模型「%s」(UUID: %s) 与该虚拟机所属账户的共享规则不匹配,无法挂载。\n请确认模型已共享给该账户或设为公开。", - "ORG_ZSTACK_AI_10165": "模型中心 (UUID: %s) 未找到(关联模型: 「%s」UUID: %s)。\n请检查模型中心是否已被删除。" + "ORG_ZSTACK_AI_10165": "模型中心 (UUID: %s) 未找到(关联模型: 「%s」UUID: %s)。\n请检查模型中心是否已被删除。", + "ORG_ZSTACK_NETWORK_ZNS_10043": "为 ZNS 三层网络[uuid:%s]分配 DHCPv4 服务 IP 失败", + "ORG_ZSTACK_NETWORK_ZNS_10044": "无法启用 DHCP:三层网络[uuid:%s]没有可用的 IP 范围(不包含 SLAAC)", + "ORG_ZSTACK_NETWORK_ZNS_10045": "无法启用 DHCP:三层网络[uuid:%s]没有云端预留的 DHCPv4 服务 IP", + "ORG_ZSTACK_NETWORK_ZNS_10046": "网段[uuid:%s]上已存在 DHCP 服务,但 GET 返回为空", + "ORG_ZSTACK_NETWORK_ZNS_10047": "无法更新 DHCP:三层网络[uuid:%s]没有云端预留的 DHCPv4 服务 IP", + "ORG_ZSTACK_NETWORK_ZNS_10048": "为 ZNS 三层网络[uuid:%s]分配 DHCPv4 服务 IP 失败" } diff --git a/utils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java b/utils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java index e406468f95a..24ae483e3b4 100644 --- a/utils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java +++ b/utils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java @@ -12124,6 +12124,12 @@ public class CloudOperationsErrorCode { // 10040 ZNS did not return Cloud allocated IP version // 10041 VM NIC MAC update is not supported for ZNS NICs // 10042 L3Network not found while enabling ZNS DHCP + // 10043 failed to allocate DHCPv4 server IP in ZNS DHCP helper + // 10044 ZNS DHCP enable has no eligible IpRange + // 10045 ZNS DHCP enable has no Cloud-reserved DHCPv4 server IP + // 10046 ZNS DHCP 409 fallback GET returned empty + // 10047 ZNS DHCP update has no Cloud-reserved DHCPv4 server IP + // 10048 failed to allocate DHCPv4 server IP in ZNS DHCP backend public static final String ORG_ZSTACK_NETWORK_ZNS_10035 = "ORG_ZSTACK_NETWORK_ZNS_10035"; public static final String ORG_ZSTACK_NETWORK_ZNS_10036 = "ORG_ZSTACK_NETWORK_ZNS_10036"; public static final String ORG_ZSTACK_NETWORK_ZNS_10037 = "ORG_ZSTACK_NETWORK_ZNS_10037"; @@ -12132,6 +12138,12 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_NETWORK_ZNS_10040 = "ORG_ZSTACK_NETWORK_ZNS_10040"; public static final String ORG_ZSTACK_NETWORK_ZNS_10041 = "ORG_ZSTACK_NETWORK_ZNS_10041"; public static final String ORG_ZSTACK_NETWORK_ZNS_10042 = "ORG_ZSTACK_NETWORK_ZNS_10042"; + public static final String ORG_ZSTACK_NETWORK_ZNS_10043 = "ORG_ZSTACK_NETWORK_ZNS_10043"; + public static final String ORG_ZSTACK_NETWORK_ZNS_10044 = "ORG_ZSTACK_NETWORK_ZNS_10044"; + public static final String ORG_ZSTACK_NETWORK_ZNS_10045 = "ORG_ZSTACK_NETWORK_ZNS_10045"; + public static final String ORG_ZSTACK_NETWORK_ZNS_10046 = "ORG_ZSTACK_NETWORK_ZNS_10046"; + public static final String ORG_ZSTACK_NETWORK_ZNS_10047 = "ORG_ZSTACK_NETWORK_ZNS_10047"; + public static final String ORG_ZSTACK_NETWORK_ZNS_10048 = "ORG_ZSTACK_NETWORK_ZNS_10048"; public static final String ORG_ZSTACK_PREMIUM_EXTERNALSERVICE_MARKETPLACE_10000 = "ORG_ZSTACK_PREMIUM_EXTERNALSERVICE_MARKETPLACE_10000"; From 7151c70fad0ae6dddd0c72fb994b6e1329ab752d Mon Sep 17 00:00:00 2001 From: "shixin.ruan" Date: Tue, 19 May 2026 13:56:14 +0800 Subject: [PATCH 5/6] [zns]: dedupe dhcp msg tags JIRA: ZCF-3703 Remove the duplicate systemTags field from SdnControllerEnableDHCPMsg. NeedReplyMessage already owns systemTags, so redeclaring it makes Gson fail while CloudBus logs the message before sending it to the ZNS DHCP handler. Change-Id: I4546348c9fd45004e0f9b9c823f9cccec9ad4774 --- .../header/network/l3/SdnControllerEnableDHCPMsg.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/header/src/main/java/org/zstack/header/network/l3/SdnControllerEnableDHCPMsg.java b/header/src/main/java/org/zstack/header/network/l3/SdnControllerEnableDHCPMsg.java index c3255f4c0e5..ade67404bd8 100644 --- a/header/src/main/java/org/zstack/header/network/l3/SdnControllerEnableDHCPMsg.java +++ b/header/src/main/java/org/zstack/header/network/l3/SdnControllerEnableDHCPMsg.java @@ -3,12 +3,9 @@ import org.zstack.header.message.NeedReplyMessage; import org.zstack.header.network.sdncontroller.SdnControllerMessage; -import java.util.List; - public class SdnControllerEnableDHCPMsg extends NeedReplyMessage implements SdnControllerMessage { private String l3NetworkUuid; private String sdnControllerUuid; - private List systemTags; public String getL3NetworkUuid() { return l3NetworkUuid; @@ -26,12 +23,4 @@ public String getSdnControllerUuid() { public void setSdnControllerUuid(String sdnControllerUuid) { this.sdnControllerUuid = sdnControllerUuid; } - - public List getSystemTags() { - return systemTags; - } - - public void setSystemTags(List systemTags) { - this.systemTags = systemTags; - } } From 3a95fa760ed3fb36f25dbdc79baaf76942ed7eda Mon Sep 17 00:00:00 2001 From: "shixin.ruan" Date: Wed, 20 May 2026 09:56:37 +0900 Subject: [PATCH 6/6] [network]: lazily load mtu extensions Avoid NPE when MtuGetter is constructed outside Spring. Resolves: ZCF-3703 Change-Id: I21a88fca05ab157a767d569435c2d37a48d4179b --- .../java/org/zstack/network/service/MtuGetter.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/network/src/main/java/org/zstack/network/service/MtuGetter.java b/network/src/main/java/org/zstack/network/service/MtuGetter.java index 9635ca3f0f5..b53da773b90 100644 --- a/network/src/main/java/org/zstack/network/service/MtuGetter.java +++ b/network/src/main/java/org/zstack/network/service/MtuGetter.java @@ -3,6 +3,7 @@ import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.Platform; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.Q; import org.zstack.header.network.l2.*; @@ -28,6 +29,13 @@ public class MtuGetter { @Autowired private PluginRegistry pluginRgty; + private PluginRegistry getPluginRegistry() { + if (pluginRgty == null) { + pluginRgty = Platform.getComponentLoader().getComponent(PluginRegistry.class); + } + return pluginRgty; + } + public Integer getMtu(String l3NetworkUuid) { String l2NetworkUuid = Q.New(L3NetworkVO.class).select(L3NetworkVO_.l2NetworkUuid).eq(L3NetworkVO_.uuid, l3NetworkUuid).findValue(); @@ -43,7 +51,7 @@ public Integer getMtu(String l3NetworkUuid) { } L2NetworkVO l2VO = Q.New(L2NetworkVO.class).eq(L2NetworkVO_.uuid, l2NetworkUuid).find(); - for (L2NetworkDefaultMtu e : pluginRgty.getExtensionList(L2NetworkDefaultMtu.class)) { + for (L2NetworkDefaultMtu e : getPluginRegistry().getExtensionList(L2NetworkDefaultMtu.class)) { if (l2VO.getType().equals(e.getL2NetworkType())) { mtu = e.getDefaultMtu(L2NetworkInventory.valueOf(l2VO)); } @@ -82,7 +90,7 @@ public Integer getL2Mtu(L2NetworkInventory l2Inv) { } /* compare to default mtu */ - for (L2NetworkDefaultMtu e : pluginRgty.getExtensionList(L2NetworkDefaultMtu.class)) { + for (L2NetworkDefaultMtu e : getPluginRegistry().getExtensionList(L2NetworkDefaultMtu.class)) { if (l2Inv.getType().equals(e.getL2NetworkType())) { Integer l2mtu = e.getDefaultMtu(l2Inv); if (mtu == null) {