Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: apache/cloudstack
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: main
Choose a base ref
...
head repository: apache/cloudstack
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: direct-routed-network
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 7 commits
  • 43 files changed
  • 1 contributor

Commits on Sep 3, 2026

  1. Direct Routed (L3) guest networks: route public IPv4/IPv6 directly to…

    … Instances
    
    Adds a new guest network type in which the hypervisor performs L3 routing
    for the Instance: no Virtual Router, no NAT and no DHCP. Each Instance
    receives a public IPv4 address as a /32 and/or an IPv6 address as a /128,
    with a shared, host-independent gateway (169.254.0.1 and fe80::1) that
    every hypervisor carries on the network's bridge. All addressing reaches
    the Instance exclusively via ConfigDrive/cloud-init; a routing daemon on
    the host (FRR, BIRD, ...) advertises the addresses to the fabric and is
    deliberately out of scope for CloudStack.
    
    Management server:
    - GuestType.L3; the guest_type column is char(32), so no schema change.
    - Offering validation: UserData via ConfigDrive is mandatory, Dns optional
      but ConfigDrive-only, SecurityGroup permitted (now allowed for L3
      alongside Shared), Dhcp rejected as not supported and not needed.
      Network mode, specifyVlan and VPC use are rejected.
    - DirectRoutedNetworkGuru subclasses DirectNetworkGuru, inheriting the
      Shared-network address lifecycle. canHandle() selects on the offering's
      guest type alone; design() produces a Native broadcast domain with no
      isolation id. After allocation the NicProfile is forced into host-route
      form, which is also the signature by which the agent and ConfigDrive
      recognise these NICs.
    - createNetwork treats L3 like Shared for the subnet: explicit IP range
      mandatory, vlan/IP-range row created at network creation, IPv6 accepted
      without the /64 restriction, aclType Account.
    - Zone-wide IPv4 overlap validation for L3 ranges: all L3 subnets share
      one host routing table and one fabric, so an overlap is an address
      conflict. The IPv6 vlan check was already zone-wide.
    
    ConfigDrive:
    - Network data is always generated for a direct routed NIC; the historical
      gate (Dhcp or Dns supported) held while ConfigDrive supplemented a VR
      but would leave these NICs with no addressing at all. Route generation
      itself is unchanged: cloud-init detects an IPv4 gateway inside
      169.254.0.0/16 and sets on-link on the rendered route by itself.
    
    KVM agent:
    - One uplink-less bridge per network, brdr-<network id>, created and
      removed by the new modifybrdr.sh (flock'd, idempotent, refuses to remove
      a bridge still in use). The bridge carries the gateway addresses,
      forwarding and strict rp_filter; separate bridges make isolation between
      networks topological rather than a filtering concern.
    - BridgeVifDriver plugs direct routed NICs into their brdr bridge and runs
      the existing modifymacip.sh hook per NIC to install the static neighbour
      entry and host route, regardless of the host-wide EVPN property, whose
      meaning is unchanged.
    
    The design document, including the decision log and the verification notes
    behind each choice, is added under docs/design/.
    wido committed Sep 3, 2026
    Configuration menu
    Copy the full SHA
    a24c841 View commit details
    Browse the repository at this point in the history

Commits on Sep 4, 2026

  1. Direct Routed networks: ROUTED isolation method and routed://<id> bro…

    …adcast domains
    
    Revises the isolation model of Direct Routed (L3) networks. A network is
    now direct routed when its offering's guest type is L3 AND it lives on a
    dedicated physical network carrying the new isolation method ROUTED --
    the network operator's explicit, zone-level opt-in. Every network gets a
    broadcast domain of the new type routed://<id>, and that id names the
    per-network bridge on the hypervisors: routed://5828 -> brdr-5828. The
    id is a label, never an encapsulation; nothing appears on the wire.
    
    The id lifecycle reuses the Shared network's VLAN mechanics verbatim:
    with specifyVlan the operator passes the id at network creation through
    the existing vlan parameter (bridge names become plannable, so host
    routing policy per brdr-<id> can exist before the network does); without
    it the id is allocated from the ROUTED physical network's vnet range at
    creation and released on deletion. Zone-wide URI overlap checks apply.
    
    Management server:
    - BroadcastDomainType.Routed ("routed", Long).
    - DirectRoutedNetworkGuru registers IsolationMethod("ROUTED") and follows
      the standard guru contract (isMyIsolationMethod); design() stamps the
      Routed broadcast domain and carries the routed:// URI.
    - encodeVlanIdIntoBroadcastUri() maps a ROUTED physical network to
      routed://<id>; the network's broadcast domain type is derived from the
      URI scheme instead of hard-coded Vlan.
    - The Shared-without-specifyVlan vnet allocation/release paths extend to
      L3; L3 offerings may carry specifyVlan either way.
    - An L3 IPv6 subnet longer than /64 is rejected at network creation:
      addresses are computed with EUI-64 from subnet + MAC (the existing
      setNicIp6Address()/updateNicIpv6() behaviour -- no address pool exists,
      only the allocated result on the NIC), and EUI-64 needs 64 bits.
    
    SystemVMs (CPVM/SSVM), dual-stack from the start:
    - PublicNetworkGuru stamps NICs of a routed public range (created with
      vlan=routed://<id>) in host-route form: /32 + 169.254.0.1, /128 +
      fe80::1, Routed broadcast domain. IPv6 comes from the same EUI-64
      computation as everywhere else.
    - The CPVM and SSVM boot-arg builders emit eth<N>ip6, eth<N>ip6prelen
      and ip6gateway, as the VR builder already did.
    - common.sh marks the v4 default route onlink for link-local gateways,
      and installs a static v6 default from the previously parsed-but-unused
      IP6GW -- on a direct routed bridge no RA ever arrives.
    
    KVM agent:
    - BridgeVifDriver recognises direct routed NICs by broadcast type
      instead of inferring from the address form, for guest and public
      traffic alike, and derives the bridge from the NIC's broadcast URI.
      modifybrdr.sh mechanics are unchanged; -n is now the routed id.
    
    UI: ROUTED joins the isolation method choices (zone wizard, physical
    network form). The design document records the revision and rationale;
    no schema change and no data migration.
    wido committed Sep 4, 2026
    Configuration menu
    Copy the full SHA
    526934c View commit details
    Browse the repository at this point in the history
  2. Direct Routed networks: audit fixes after the isolation-model overhaul

    Reviewing every path the overhaul touches surfaced four fixes:
    
    - SystemVM public IPv6 is now computed directly in PublicNetworkGuru
      (EUI-64 from the range's ip6_cidr and the NIC MAC, then /128 + fe80::1).
      The previously planned ipv6Service.updateNicIpv6() path is unusable
      here: it is gated on the public network offering's internet protocol
      (never set on the system public offering) and reserves through one
      placeholder NIC per network -- on the shared Public network, every
      SystemVM would have received the same address.
    - Guest networks and public ranges share one routed-id space (a routed
      id names a bridge on every host), so collisions between them would
      merge L2 domains. Both directions are now rejected: a guest network
      cannot take an id a public range carries, and a public range cannot
      take an id a guest network holds.
    - Creating an L3 network on a physical network without the ROUTED
      isolation method now fails early with a clear message, instead of an
      opaque no-guru error deep in setupNetwork().
    - A direct routed guest NIC's isolation URI now mirrors its routed://
      broadcast URI instead of the misleading vlan://<tag> inherited from
      the Shared allocation path.
    
    GuestType.L3 itself was re-verified as still required: some thirty
    management-server branches (offering validation, subnet handling,
    zone-wide overlap checks, secondary-IP host routes, security groups)
    key on the guest type in places where no physical network -- and thus
    no isolation method -- is in scope. The guest type says what a network
    is; the isolation method says where it may live.
    wido committed Sep 4, 2026
    Configuration menu
    Copy the full SHA
    5bfa524 View commit details
    Browse the repository at this point in the history
  3. test: update CreateNetworkCmdTest for the L3-aware physical network I…

    …D message
    
    CreateNetworkCmd.getPhysicalNetworkId() now accepts guest type L3 and its
    error message reads 'Shared, L2 or L3 only'; the test still asserted the
    old 'Shared or L2 only' text and failed.
    wido committed Sep 4, 2026
    Configuration menu
    Copy the full SHA
    feb6102 View commit details
    Browse the repository at this point in the history

Commits on Sep 5, 2026

  1. Direct Routed networks: DefaultL3NetworkOffering and ROUTED in the re…

    …maining UI form
    
    Add a default network offering for Direct Routed (L3) guest networks,
    DefaultL3NetworkOffering: UserData and DNS via ConfigDrive, Security
    Groups enabled - the only service set validateL3NetworkOffering()
    permits. It is created in NetworkOrchestrator.configure() like the
    other default offerings, so it appears on fresh installs and on
    upgrades alike; until now the operator had to create it by hand.
    The routed id is allocated from the ROUTED physical network's range
    (no specifyVlan).
    
    UI: the ROUTED isolation method was selectable in the zone wizard and
    in the infrastructure listing's add-physical-network form, but missing
    from the form on a zone's Physical Networks tab - add it there. Give
    the VLAN, VXLAN and ROUTED options hover descriptions explaining what
    each isolation method does, so operators understand what they are
    opting into; ROUTED's spells out the Direct Routed model (no VLANs on
    the wire, no Virtual Router, no DHCP, addressing via ConfigDrive, L3
    offerings only, KVM only).
    wido committed Sep 5, 2026
    Configuration menu
    Copy the full SHA
    8275a0c View commit details
    Browse the repository at this point in the history
  2. Direct Routed networks: skip the PVLAN overlap check for routed:// URIs

    Creating an L3 network died in NetworkOrchestrator.createGuestNetwork():
    after encodeVlanIdIntoBroadcastUri() produced routed://<id>, the
    unconditional PVLAN overlap check handed that URI to
    listByPhysicalNetworkPvlan(), which rejects every URI scheme other than
    vlan:// and vxlan://:
    
      'Requested URI routed://189 is not in the expected format. Expected
       URI Scheme as vlan://VID or vxlan://VID.'
    
    The check is meaningless for a routed id: no PVLAN network can exist on
    a ROUTED physical network (only L3 networks can), and the id's real
    overlap checks - zone-wide URI, public ranges, the vnet range - have
    already run earlier in the method. Skip it when the URI scheme is
    routed.
    
    Also reject the isolatedpvlan parameter for L3 networks explicitly, so
    the pvlan branch (which would build a pvlan:// URI around the routed id)
    is unreachable for this guest type.
    wido committed Sep 5, 2026
    Configuration menu
    Copy the full SHA
    e5f1b64 View commit details
    Browse the repository at this point in the history
  3. Direct Routed networks: let the UI pass an operator-chosen routed id

    CreateL3NetworkForm only supported offerings that allocate the routed id
    automatically; an operator-chosen id (the API's vlan parameter, like a
    Shared network's VLAN tag) could be given through the API alone. Add a
    'Routed ID' field to the form, shown to root admins when the selected
    L3 offering carries specifyVlan - where the API requires the id - and
    hidden otherwise, since the API then rejects the parameter and
    allocates the id from the ROUTED physical network's range.
    
    The field's description explains what the id is: a label naming the
    per-network bridge (brdr-<id>) on every KVM host, unique per zone,
    nothing on the wire, and useful to choose in advance so host routing
    policy can exist before the network does.
    wido committed Sep 5, 2026
    Configuration menu
    Copy the full SHA
    34a103e View commit details
    Browse the repository at this point in the history
Loading