Skip to content

KVM: Support multi vlan trunk NICs - #14166

Draft
Pearl1594 wants to merge 86 commits into
mainfrom
support-multi-vlan-guestnet
Draft

Pearl1594 wants to merge 86 commits into
mainfrom
support-multi-vlan-guestnet

Conversation

@Pearl1594

@Pearl1594 Pearl1594 commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Description

This PR adds support for multi-vlan trunk NICs

doc PR: apache/cloudstack-documentation#689

https://cwiki.apache.org/confluence/spaces/CLOUDSTACK/pages/451972290/Multi+VLAN+trunk+NICs+support+in+KVM

  • Added multi-VLAN trunk NIC support for KVM: a single VM NIC can now be associated with multiple existing, ordinary single-VLAN guest networks simultaneously, delivered via libvirt's native XML (libvirt ≥11.0.0) or a manual bridge vlan add/del fallback on older libvirt.
  • New nic_network_map table and nics.multi_network flag to track a NIC's additional network associations, fully additive, zero behavior change for any NIC with no associations.
  • Host capability tracking: new vlan.filtering.enabled and vlan.trunk.xml.supported host details, surfaced via HostResponse, gating placement, deployment, and migration decisions.
  • New admin-only APIs: associateNetworkToNic and disassociateNetworkFromNic, with per-association IP support and duplicate-VLAN/CIDR-overlap validation.
  • VM deploy and VNF appliance support via a new nicnetworkslist parameter, letting a trunk NIC be requested directly at deploy time; VNF management NICs are explicitly blocked from being trunked.
  • DHCP delivery to every associated network, not just the primary, including correct behavior for VPC-tier associations sharing one virtual router.
  • Guest-side VLAN discovery via a new nic-vlan-mapping metadata entry, letting a VNF or guest script learn its associated networks' VLAN tags without hardcoding.
  • Static NAT, Port Forwarding, and Load Balancing rules widened to target an address on any of a NIC's associated networks, not just its primary.
  • Usage and billing events extended to bill every network a trunk NIC is associated with, not only its primary; a related pre-existing billing bug found and queued as a separate fix. (Usage: Fix usage_network_offering row mismatches on nic removal and default-nic swap #14341)
  • Migration support: destination-capability-driven interface XML regeneration so a VM can move between hosts with different bridge models or libvirt capabilities; one real cross-boundary migration bug found and fixed.
  • Dropped the original same-VPC-only restriction on trunk associations; a NIC can now be associated with tiers of different VPCs, since per-network access checks and VPC ACL enforcement already apply correctly regardless of VPC membership.
  • UI support: NICs tab associate/disassociate with a loop-risk warning, deploy wizard NIC grouping, VNF wizard multi-select, host and zone readiness indicators, and migration dialog unsuitability reasons.
  • Fixed a pre-existing, unrelated UI bug where a previously selected network was lost when paging through the network list in the deploy wizard.

Types of changes

  • Breaking change (fix or feature that would cause existing functionality to change)
  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Enhancement (improves an existing feature and functionality)
  • Cleanup (Code refactoring and cleanup, that may add test cases)
  • Build/CI
  • Test (unit or integration test code)

Feature/Enhancement Scale or Bug Severity

Feature/Enhancement Scale

  • Major
  • Minor

Screenshots (if appropriate):

How Has This Been Tested?

Core trunk mechanism (KVM delivery)

  • Trunk NIC wire-level delivery confirmed via bridge vlan show: primary network native/untagged, each associated network tagged-only, on both the native-libvirt-XML path and the manual bridge vlan add fallback path.
  • Real cross-host and same-host guest connectivity confirmed (ARP + ping) on associated networks, including a VM with two independently-trunked NICs on different network sets simultaneously.
  • Host bridge-readiness and libvirt trunk-XML capability detection confirmed via host details and the Hosts list UI badge.

Association lifecycle

  • Live associateNetworkToNic / disassociateNetworkFromNic on a Running VM, including re-association after a prior disassociation.
  • changeNicPrimaryNetwork on a stopped VM, confirmed via console that the guest correctly reacquired the new primary's address via DHCP, plus a real ping round-trip after restart.
  • nics.multi_network flag correctly set and cleared across the full associate/disassociate lifecycle.

Cross-VPC trunk associations

  • created a second VPC, associated one of its tiers onto a NIC whose primary was a tier of a separate VPC, confirmed via API (trunked:true, correct associated network) and via bridge vlan show on the host.
  • Real cross-host guest-to-guest ping (0% loss) between the trunk NIC's associated-network VLAN sub-interface and a probe VM on the second VPC's tier.

VM deploy and VNF

  • Deploy-time nicnetworkslist trunk creation, including a VM mixing trunk and ordinary NICs in one deploy.
  • VNF management-NIC-cannot-be-trunked rejection, both at deploy time and via live associate.
  • A 3-NIC VNF template with two independently-trunked data-plane NICs, deploy + wire-level + DHCP + ping all confirmed for both.
  • Static NAT, Port Forwarding, and Load Balancing rules created and confirmed reachable against a trunk NIC's associated-network address.
  • Plain/legacy non-trunk VM regression pass: deploy, stop/start, PF/LB/Static NAT, DHCP entries and NIC state confirmed byte-identical before and after.

Network type coverage

  • L2, Shared (no security groups), and VPC-tier trunk associations all deploy- and wire-level confirmed on one VM covering all three in a single test pass.
  • CIDR-overlap rejection confirmed at both the live-associate and deploy-time paths.

DHCP correctness

  • trunk NIC's associated networks receive a DHCP entry
  • Confirmed DHCP correctness for VPC-tier trunk associations, where a primary and association share one VPC virtual router: both leases obtained simultaneously on the same NIC, verified live. Also regression-checked against L2 and Shared network types to confirm they're unaffected.

Usage and billing

  • Full usage/billing test pass run against the real nightly usage job, hour-level figures hand-verified against raw event timestamps: network-offering-change propagation, deploy-time trunk billing, changeNicPrimaryNetwork role swap, and live associate/disassociate billing immediately rather than waiting for next VM start, all confirmed passing.
  • Found and fixed a real, pre-existing (non-trunk-specific) bug in default-NIC-swap billing that silently wiped billing for the nic becoming default.

Migration

  • Full matrix run live across mixed-capability clusters: intra-cluster boundary crossing in both directions, trunk NICs correctly hard-blocked from crossing a non-filtering-enabled boundary, cross-cluster migration forcing storage motion, a multi-NIC VM (two independently trunked NICs) migrated cross-cluster with each NIC's wire configuration verified independently, host-readiness gating confirmed via both the migration host list and fully-automatic planner-driven migration, and a migration crossing both the libvirt-capability and bridge-readiness boundaries at once.
  • legacy-to-shared-bridge migration for ordinary (non-trunk) multi-NIC VMs in both directions, single-NIC and multi-NIC.
  • Real post-migration connectivity confirmed (0% loss) on both primary and associated VLANs.

AssignVirtualMachine to another account

  • tested moving a VM from admin to a new account having a trunked nic (1 primary network and 1 associated network)

UI

  • NICs tab: trunked badge, associated-networks list with disassociate action, admin-gated Associate Network modal.
  • Deploy wizard and VNF deploy wizard: multi-network grouping control with loop-risk warning, confirmed not to regress a non-grouped deploy.
  • Migration dialog: unsuitable-host tooltip confirmed showing the correct reason.
  • Host and zone readiness badges/rollup confirmed live.

How did you try to break this feature and the system with this change?

shwstppr and others added 2 commits September 14, 2026 15:29
Adds a 4.23.0 to 24.0.0 upgrade path (squashed from sb/upgradepath-424:
engine-schema: upgrade path for 24.0.0, fix CS version, fix upgrade
unit tests for cutover, fix imports).
@github-actions

Copy link
Copy Markdown

This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch.

@codecov

codecov Bot commented Sep 14, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 58.60239% with 936 lines in your changes missing coverage. Please review.
✅ Project coverage is 20.67%. Comparing base (e9af62c) to head (d644d6e).
⚠️ Report is 9 commits behind head on main.

Files with missing lines Patch % Lines
...ain/java/com/cloud/network/NetworkServiceImpl.java 73.26% 114 Missing and 36 partials ⚠️
.../src/main/java/com/cloud/vm/UserVmManagerImpl.java 60.79% 55 Missing and 14 partials ⚠️
...tack/engine/orchestration/NetworkOrchestrator.java 40.17% 59 Missing and 8 partials ⚠️
...cloudstack/api/response/NicNetworkMapResponse.java 0.00% 55 Missing ⚠️
...cloud/hypervisor/kvm/resource/BridgeVifDriver.java 67.45% 47 Missing and 8 partials ⚠️
...loudstack/api/command/user/vm/BaseDeployVMCmd.java 66.96% 26 Missing and 11 partials ⚠️
...ervisor/kvm/resource/LibvirtComputingResource.java 14.28% 36 Missing ⚠️
...in/java/com/cloud/vm/dao/NicNetworkMapDaoImpl.java 24.44% 34 Missing ⚠️
server/src/main/java/com/cloud/api/ApiDBUtils.java 0.00% 32 Missing ⚠️
...n/java/com/cloud/vm/VirtualMachineManagerImpl.java 28.57% 30 Missing ⚠️
... and 45 more
Additional details and impacted files
@@             Coverage Diff              @@
##               main   #14166      +/-   ##
============================================
  Coverage     20.66%   20.67%              
+ Complexity    21723    20716    -1007     
============================================
  Files          6492     6049     -443     
  Lines        590728   547505   -43223     
  Branches      72448    73132     +684     
============================================
- Hits         122054   113174    -8880     
+ Misses       455404   421071   -34333     
+ Partials      13270    13260      -10     
Flag Coverage Δ
uitests 3.86% <ø> (+0.12%) ⬆️
unittests 22.09% <58.60%> (+0.12%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Sep 14, 2026 •

Copy link
Copy Markdown

🔴 Test Coverage Grade: D — Marginal

Metric Value
Line coverage 25.55%
Branch coverage 20.71%

Grade Scale

Grade Line Coverage Meaning
🟢 A ≥ 80% Excellent - this code sleeps well at night 😴
🟡 B 60-79% Good - almost there, don't stop now 😉
🟠 C 40-59% Acceptable - your code is wearing a seatbelt, but no airbags 😬
🔴 D 20-39% Marginal - boldly shipping where no test has gone before 🖖
⛔ F < 20% Failing - tests? what tests? 🔥

Branch coverage is shown as a secondary signal. Grade is determined by line coverage.
View full Actions run

@github-actions

Copy link
Copy Markdown

This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch.

The (nic_id, network_id) unique key rejected re-associating a network
after a prior disassociate, since the old row's uniqueness survives as
a soft-deleted (removed) row. Switch to a plain index so re-association
after disassociation works, relying on application-level checks (not
the DB) to reject a true duplicate live association.
…fallback

Trunk NIC VLAN membership is delivered by reusing the existing guest
bridge with vlan_filtering=1: the primary VLAN gets native/untagged
membership, associated VLANs get tagged-only membership, via libvirt's
<vlan trunk='yes'> element where supported, or manual `bridge vlan add`
on older libvirt. Adds a live membership update path
(UpdateNicVlanMembershipCommand/Answer + its KVM wrapper) so an
association change on a running VM is pushed to the host without a
restart, and a non-blocking diagnostic warning when the physical
uplink is missing a VLAN a trunk NIC needs (CloudStack no longer
manages the uplink's own VLAN membership - that is the operator's
responsibility).
- New UsageEventUtils.publishNicNetworkOfferingUsageEvents() emits one
  usage event per network a nic bills against (primary + any trunk
  associations), replacing the old single-event publishUsageEvent at
  every NIC-billing call site
- Ordinary non-trunk nics still produce exactly one event, unchanged
- New nullable usage_network_offering.network_id column disambiguates
  rows when a trunk nic's networks share one network offering
- Backfills network_id on a nic's own still-open usage row(s) the
  moment it first converts to a trunk nic; historic rows otherwise
  left alone
- New NicNetworkMapResponse + trunked/associatednetworks fields on
  NicResponse
- Populated in listNics, listVirtualMachines, and the
  associate/disassociate/change-primary command responses
- Trunk status derived from nic_network_map rows rather than a new
  column on the wide UserVmJoinVO view
- ASSOCIATED_NETWORKS/TRUNKED, needed by the previous commit's
  NicResponse fields
Core capability:
- New associateNetworkToNic/disassociateNetworkFromNic/changeNicPrimaryNetwork
  admin APIs and associateNetworksToNic (programmatic, used by deploy)
- A nic keeps one primary network plus any number of additional
  associated networks (nic_network_map), delivered as a VLAN trunk
- changeNicPrimaryNetwork only allowed while the Instance is stopped
- Rejects associating a network already reachable via another of the
  VM's nics, or with an overlapping CIDR to an existing association
- Disassociating a network is blocked while an active PF/Static
  NAT/LB rule targets its allocated IP

PF/Static NAT/LB support for associated networks:
- NetworkModel.getNicAndIpInNetwork resolves a nic/guest-ip pair via
  the nic's primary match or a trunk association, reused by
  RulesManagerImpl and LoadBalancingRulesManagerImpl so these rules
  can target a trunk nic's associated networks, not just its primary

Deployment planning:
- Hosts without VLAN filtering enabled are excluded up front for any
  VM with a multi-VLAN trunk nic, with a reactive fallback exclusion
  during start as a backstop
- Removing a nic cleans up any trunk associations it held as primary;
  deleting a network is blocked while still associated as a secondary

Metadata:
- A trunk nic's associated-network VLAN tags are exposed to the guest
  via the metadata service (nic-vlan-mapping file), gated by a new
  account-scoped config key, off by default
- EVENT_NIC_NETWORK_ASSOCIATE/DISASSOCIATE/PRIMARY_NETWORK_CHANGE,
  needed by the previous commit's @actionevent annotations
- New nicnetworkslist deploy param (nicnetworkslist[N].networkids,
  first id primary) lets a VM be deployed with trunk nics directly,
  mutually exclusive with networkids/iptonetworklist/vApp nicnetworklist
- Also carries per-entry ip4address/ip6address for the primary and
  ip4addresses/ip6addresses (comma-separated) for its associated
  networks - a network with no requested IP auto-allocates
- VNF: rejects a management-device nic from being requested as a
  trunk, both at deploy time and via the live associate API
- checkNoActiveRulesOnAssociation used findByIpAndNetworkId, which
  matches on a public IP's own address - the association's IP is a
  guest IP, so this never matched and the guard silently let
  disassociation through even with an active static NAT rule
- Use findByAssociatedVmIdAndVmIp instead, which matches the actual
  static NAT target mapping
- validateVnfApplianceTrunkNics only ran at deploy time
  (nicnetworkslist) - the live associateNetworkToNic/associateNetworksToNic
  path had no equivalent check, so a VNF's management nic could be
  trunked after deploy
- New single-nic validateVnfApplianceTrunkNic, called from
  associateNetworksInternal so both entry points are covered
- No-op for any non-VNF template
- changeNicPrimaryNetwork updated networkId and the IPv4/IPv6 address
  but left gateway, netmask, broadcast/isolation uri, and IPv6
  gateway/cidr pointing at the old primary network - wrong
  indefinitely, since nothing else ever recomputes them
- New applyNetworkAddressingToNic refreshes them from the new primary
  network, mirroring the field derivation used when a nic is first
  created
- disassociateNetworkFromNic now clears nics.multi_network once
  nic_network_map has no remaining rows for that nic
- Without this, listNics/listVirtualMachines kept reporting trunked=true
  and the deployment planner kept restricting the VM to VLAN-filtering-
  capable hosts even after all associations were removed
- New CommandSetupHelper.createDhcpEntryCommand overload takes addressing
  explicitly instead of reading it off a NicVO, since a nic's own DB row
  only ever carries its primary network's IP/gateway
- NetworkServiceImpl sends the entry directly to the associated network's
  router(s) on live associate/disassociate, bypassing the
  DhcpServiceProvider pipeline (which re-resolves the nic from the DB and
  so can never see anything but the primary IP)
- UserVmManagerImpl.finalizeStart converges a nic's associated-network
  DHCP entries with its current nic_network_map rows on every VM start,
  covering associations made while the VM was stopped and cleaning up
  entries for associations removed while stopped
- New NicNetworkMapDao.listRemovedByNicId to support that cleanup
@blueorangutan

Copy link
Copy Markdown

@Pearl1594 a [SL] Jenkins job has been kicked to build packages. It will be bundled with no SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 19815

@Pearl1594

Copy link
Copy Markdown
Contributor Author

@blueorangutan test

@blueorangutan

Copy link
Copy Markdown

@Pearl1594 a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests

@blueorangutan

Copy link
Copy Markdown

[SF] Trillian test result (tid-17318)
Environment: kvm-ol8 (x2), zone: Advanced Networking with Mgmt server ol8
Total time taken: 56549 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr14166-t17318-kvm-ol8.zip
Smoke tests completed. 155 look OK, 2 have errors, 0 did not run
Only failed and skipped tests results shown below:

Test Result Time (s) Test File
ContextSuite context=TestCloudStackDNSFramework>:setup Error 0.00 test_dns_framework_powerdns.py
test_01_RVR_Network_FW_PF_SSH_default_routes_egress_true Failure 189.58 test_routers_network_ops.py

@Pearl1594

Copy link
Copy Markdown
Contributor Author

@blueorangutan test

@blueorangutan

Copy link
Copy Markdown

@Pearl1594 a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests

… and live nic add, using the network's VLAN when the nic has none
@Pearl1594

Copy link
Copy Markdown
Contributor Author

@blueorangutan package

@blueorangutan

Copy link
Copy Markdown

@Pearl1594 a [SL] Jenkins job has been kicked to build packages. It will be bundled with no SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✖️ el8 ✖️ el9 ✔️ debian ✔️ suse15. SL-JID 19856

@Pearl1594

Copy link
Copy Markdown
Contributor Author

@blueorangutan package

@blueorangutan

Copy link
Copy Markdown

@Pearl1594 a [SL] Jenkins job has been kicked to build packages. It will be bundled with no SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 19858

@blueorangutan

Copy link
Copy Markdown

[SF] Trillian test result (tid-17333)
Environment: kvm-ol8 (x2), zone: Advanced Networking with Mgmt server ol8
Total time taken: 61242 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr14166-t17333-kvm-ol8.zip
Smoke tests completed. 157 look OK, 0 have errors, 0 did not run
Only failed and skipped tests results shown below:

Test Result Time (s) Test File

…VLAN 1 nics as needing a legacy host, including in host planning
@RosiKyu

RosiKyu commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator

@blueorangutan package

@blueorangutan

Copy link
Copy Markdown

@RosiKyu a [SL] Jenkins job has been kicked to build packages. It will be bundled with no SystemVM templates. I'll keep you posted as I make progress.

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
C Reliability Rating on New Code (required ≥ B)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 19861

@Pearl1594

Copy link
Copy Markdown
Contributor Author

@blueorangutan test

@blueorangutan

Copy link
Copy Markdown

@Pearl1594 a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests

@blueorangutan

Copy link
Copy Markdown

[SF] Trillian test result (tid-17353)
Environment: kvm-ol8 (x2), zone: Advanced Networking with Mgmt server ol8
Total time taken: 56968 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr14166-t17353-kvm-ol8.zip
Smoke tests completed. 156 look OK, 1 have errors, 0 did not run
Only failed and skipped tests results shown below:

Test Result Time (s) Test File
test_01_isolate_network_FW_PF_default_routes_egress_true Failure 103.08 test_routers_network_ops.py

@Pearl1594

Copy link
Copy Markdown
Contributor Author

@blueorangutan test

@blueorangutan

Copy link
Copy Markdown

@Pearl1594 a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests

@blueorangutan

Copy link
Copy Markdown

[SF] Trillian test result (tid-17369)
Environment: kvm-ol8 (x2), zone: Advanced Networking with Mgmt server ol8
Total time taken: 58549 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr14166-t17369-kvm-ol8.zip
Smoke tests completed. 155 look OK, 2 have errors, 0 did not run
Only failed and skipped tests results shown below:

Test Result Time (s) Test File
test_router_dhcphosts Failure 20.75 test_router_dhcphosts.py
test_02_isolate_network_FW_PF_default_routes_egress_false Failure 137.62 test_routers_network_ops.py
test_01_RVR_Network_FW_PF_SSH_default_routes_egress_true Failure 213.59 test_routers_network_ops.py

@RosiKyu RosiKyu left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, based on manual QA of the head of this PR (d644d6e).

Test environment

  • KVM hosts in all three host profiles the feature supports:
    • Legacy: no VLAN filtering.
    • VLAN filtering with libvirt older than 11: Oracle Linux 9 with libvirt 9.0 and 10.10.
    • VLAN filtering with libvirt 11: Oracle Linux 9 with libvirt 11.10, and Debian 13 with libvirt 11.3.
  • An Advanced zone and a Security Group zone. Isolated, Shared, L2, VPC tier and untagged networks. Two management servers for the cross-server cases.
  • Every round was redone on each new head; the last full round was on d644d6e.

Results

  • The full test plan of 196 test cases was run, plus additional exploratory, failure injection and regression scenarios.
  • Issues found during testing were addressed in this PR and re-verified on the final build.

Areas tested

  • Host profile detection and conversion: VLAN filtering, STP and libvirt version detection, and host details, including readiness taken from the Guest traffic label when it differs from guest.network.device. Converting a Legacy host to VLAN filtering, including with VMs running, and a libvirt 9 to 11 upgrade done through maintenance.
  • Associate, disassociate and changeNicPrimaryNetwork: on running and stopped VMs, on Isolated, Shared, VPC tier and dual-stack networks, and up to 50 associations and VLAN 4094.
    • Checked after each change: IP allocation and release, router DHCP entries, the nic-vlan-mapping file, events and usage.
    • Rollback when a later network in a multi-network call fails, including the host side on libvirt older than 11.
    • Associating a network that was never implemented starts its router.
    • Two trunk NICs on one VPC tier router keep both DHCP entries.
    • With the association network's router stopped, or destroyed and recreated, the DHCP entries are rebuilt.
    • Redundant routers: entries reach both routers and survive failover.
    • Access checks: run against the VM owner, and an access error comes before "already associated".
    • listNics and listVirtualMachines on an association network: scoping, filters and paging.
  • Deploy with nicnetworkslist and assignVirtualMachine: Validation and negative paths: invalid combinations, other accounts' networks, domain admin limits, gateway and duplicate IPs, and the same network twice in one call. A rejected call leaves nothing behind.
  • On the wire: tap VLAN membership on each host profile, native and manual paths. No VLAN 1 leak, untagged frames, and VLAN hopping attempts with double tags and VLAN 1.
  • Guest side: DHCP and metadata on associated VLANs, and port forwarding, static NAT, load balancing and egress rules on associated addresses.
  • Network lifecycle guards: delete, network GC, CIDR change, offering change, migrateNetwork and migrateVpc.
  • Live migration across profiles:
    • Legacy, manual and native in each direction: the supported directions work and the others are refused with a clear message.
    • findHostsForMigration reasons and the UI tooltip.
    • HA, host maintenance, host reboot, and agent and libvirtd restarts.
  • VLAN 1 networks on converted hosts:
    • Trunk NIC plus VLAN 1 refused on every path.
    • Plain VLAN 1 VMs placed on Legacy hosts, and router, SSVM and CPVM Public NICs on VLAN 1.
    • Maintenance with and without a Legacy host available.
    • SSVM and CPVM with Management and Storage NICs on VLAN 1, run on converted hosts:
      • The Storage NIC on VLAN 1, carried on the guest uplink, gets its own VLAN 1 bridge. Secondary storage NFS mounts through it.
      • Its frames leave the host tagged VLAN 1, with nothing untagged and nothing on the guest bridge.
      • The SSVM live migrates between native, manual and Legacy hosts with storage working after each move.
      • The Management NIC is plugged untagged into the management bridge, as on stock KVM, and the agents connect.
  • Concurrency: parallel associate calls, associate against network delete, and calls spread across two management servers.
  • VM operations on trunk VMs: VM snapshots with and without memory, NIC link down and up, suspend and resume, scale, restore, destroy and recover, unmanage (refused), and projects.
  • Feature switched off in the zone: existing trunk VMs keep working and new trunk operations are refused.
  • Security Group zone: trunk NICs are refused where security groups apply.
  • UI: the association dialogs, NIC listings, address pickers for rules, and the migration wizard.
  • Regression: ordinary VMs, routers, redundant VPC failover and system VMs on Legacy and converted hosts, and usage jobs.

Not tested

  • The out of scope items from the documentation: backup and restore, VXLAN, and two untagged networks on one host.

Minor, left as is

  • A deploy or start with the hostid of a host that cannot take the VM gives the generic "No destination found". The same happens for a trunk VM with the hostid of a Legacy host.
  • The assignVirtualMachine refusal for a trunk NIC plus a VLAN 1 network shows a generic message. The reason is in the management server log.

Unrelated issues seen during testing

  • A VM start fails with an NPE in deployInVmLastHost when the VM's last host has been removed. This is on main since #12711, and stock 4.22.1.1 starts the same VM.
  • The router's dnsmasq 2.90 crashes (SIGSEGV) on reload after a DHCP entry change. This also happens on routers without associations and on stock 4.22.1.1, and it is fixed upstream in dnsmasq 2.91.
  • deleteManagementNetworkIpRange fails with an NPE ("Cannot invoke "String.equals(Object)" because "vlan" is null") when vlan is given as 1 or untagged. It works with vlan://1. This PR does not change that code.

Code coverage (Codecov at d644d6e)

  • Patch coverage is 58.60% (936 changed lines not covered by unit tests). Project coverage is 20.67%.
  • Coverage of the main changed files:
    • NetworkServiceImpl: 73.26%
    • BridgeVifDriver: 67.45%
    • BaseDeployVMCmd: 66.96%
    • UserVmManagerImpl: 60.79%
    • NetworkOrchestrator: 40.17%
    • VirtualMachineManagerImpl: 28.57%
    • NicNetworkMapDaoImpl: 24.44%
    • LibvirtComputingResource: 14.28%
  • The associate, disassociate, deploy, migration and host profile paths in these files were all exercised by the manual tests above.

Latest smoke test run

  • The last smoke run had 3 failures:
    • test_router_dhcphosts
    • test_01_RVR_Network_FW_PF_SSH_default_routes_egress_true
    • test_02_isolate_network_FW_PF_default_routes_egress_false
  • All three fail on traffic from a guest to the internet:
    • Two get 2 of 3 replies to ping -c 3 8.8.8.8, and the tests require 0% loss.
    • One runs curl -m 1 right after the egress rule was applied on the router, and it timed out.
  • The hosts in that run report vlan.filtering.enabled false, so the new VLAN filtering paths were not in use.
  • The same flows were rerun by hand on the PR build:
    • Add the egress rule for TCP 80, then run curl -m 1 at once from guests on a native and a manual host, with the router on a Legacy host: 20 of 20 got 200 OK.
    • The router's dhcphosts file lists both VMs with the right MAC and IP.
    • ping -c 3 8.8.8.8, 15 times per guest: one guest had two runs with 2 of 3 replies. The bare hosts, with no VM or router in the path, lost a reply at the same rate.
  • So the failures match packet loss on the path to the internet. The flow was not run on a stock build. The log is attached.

T-trillian-17369-lab-rerun-raw.txt

@Pearl1594

Copy link
Copy Markdown
Contributor Author

@blueorangutan test

@blueorangutan

Copy link
Copy Markdown

@Pearl1594 a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests

@blueorangutan

Copy link
Copy Markdown

[SF] Trillian Build Failed (tid-17472)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants