|Index|AI-Native Disaggregated RAN
SUSE Telco Cloud

AI-Native Disaggregated RAN

Project Sylva Reference Architecture with SUSE Telco Cloud and OCUDU RAN Stack

Technical Reference Documentation
Reference Configuration
Authors
Nils Fürste, DevOps Engineer (Software Radio Systems)
Andre Puschmann, VP of Engineering (Software Radio Systems)
Alberto Morgante, Principal Telco Engineer (SUSE)
Antonio Alonso Alarcon, Senior Telco Engineer (SUSE)
Tim Irnich, Senior Distinguished Telco Product Manager (SUSE)
SUSE Telco Cloud
OCUDU
Date: 2026-06-26
Summary

This document provides a technical reference for using OCUDU on SUSE Telco Cloud to validate hardware readiness and size resources for a selected 5G RAN configuration. The goal is not to describe a full production deployment. Instead, this reference architecture shows how to exercise the OCUDU stack, measure the resources required by the chosen RAN configuration, and use those measurements as input for planning a production deployment. In this setup, OCUDU runs in the gNB deployment variant together with an RU emulator. This allows the DU-to-RU path to be validated with O-RAN Split 7.2 and Open Fronthaul behavior while keeping the test environment fully software-based and reproducible.

Disclaimer

Documents published as part of the series SUSE Technical Reference Documentation have been contributed voluntarily by SUSE employees and third parties. They are meant to serve as examples of how particular actions can be performed. They have been compiled with utmost attention to detail. However, this does not guarantee complete accuracy. SUSE cannot verify that actions described in these documents do what is claimed or whether actions described have unintended consequences. SUSE LLC, its affiliates, the authors, and the translators may not be held liable for possible errors or the consequences thereof.

1 Introduction

Communication Service Providers (CSPs) are transitioning to open, disaggregated, and AI-native network architectures to reduce costs, eliminate vendor lock-in, and accelerate innovation in 5G and 6G services. This shift requires tight integration between carrier-grade infrastructure platforms and high-performance RAN software that can run efficiently on general-purpose hardware.

This joint reference architecture documents the technical integration of the OCUDU® RAN stack with SUSE® Telco Cloud, aligned with Project Sylva, enabling deployment of RAN with AI-native workloads. Validated in collaboration with Software Radio Systems (SRS), the technical contributor of OCUDU, it provides a single-node deployment model using Cluster API (CAPI) for hardware readiness validation and resource sizing. The setup focuses on an O-RAN Split 7.2 gNB configuration with an RU emulator, enabling fully software-based testing and repeatable performance measurements. It demonstrates production-grade performance characteristics including low latency, 1,000+ users per cell, and hardware efficiency gains of 30-50% CAPEX reduction compared to proprietary systems.

1.1 Acknowledgments

The following individuals contributed to the creation of this document:

  • Vesselin Matev, Partner Solutions Manager, SUSE

  • Jivaji Ihare, Partner Solution Architect, SUSE

  • Terry Smith, Ecosystem Solution Innovation Director, SUSE

  • Andrés Valero, Principal Technology Advocate, SUSE

2 Market challenges

The telco industry continues to operate under significant structural fragmentation. Most 5G deployments still rely on proprietary, vertically integrated hardware and software stacks from a small number of vendors. This approach creates deep vendor lock-in, inflates both capital and operational expenses, and limits operators’ ability to select best-of-breed components.

Operators face three interconnected problems. First, the lack of standardized reference architectures forces custom, site-specific integration work for every new deployment, binding CSPs to individual vendor roadmaps and increasing complexity. Second, existing open source telco infrastructure has historically fallen short of the extreme performance, deterministic latency, and resiliency requirements demanded by modern RAN workloads, especially those incorporating AI. Third, managing distributed edge environments with consistent operations remains difficult when each site uses different hardware platforms and deployment processes.

These challenges directly constrain operators. They result in prolonged deployment timelines, higher lifecycle costs, reduced innovation velocity, and slower delivery of new AI-native 5G and future 6G services that require sub-millisecond latency and high user density. Without a unified, horizontal foundation, operators struggle to scale efficiently, control their infrastructure choices, or fully capitalize on the business opportunities of edge computing and programmable networks. Also, a key gap has been the lack of validated, carrier-grade Open RAN implementations that operators can confidently deploy at scale.

3 The solution

SUSE and SRS have jointly developed a fully disaggregated, carrier-grade Open RAN stack anchored in the Project Sylva reference architecture. This solution was demonstrated at MWC 2026, validating its readiness for real-world telco deployments.

The stack is structured as a horizontal, integrated platform that begins with general-purpose hardware and extends through the infrastructure layers to the RAN workloads. At the foundation lies high-performance commodity hardware featuring Intel® Xeon® 6 SoC processors and Supermicro edge servers. This choice delivers the necessary compute density and efficiency while avoiding proprietary silos, enabling significant improvements in power consumption and server utilization.

Above the hardware, SUSE Telco Cloud provides the operating system and Kubernetes infrastructure layer. SUSE Linux Micro, an immutable and real-time Linux distribution, combined with RKE2, creates a hardened, Sylva-compliant Container-as-a-Service platform. This layer ensures deterministic low-latency performance, CPU isolation, SR-IOV networking with DPDK, and NUMA-aware resource management, all critical for meeting the stringent timing and throughput requirements of RAN workloads.

image architecture1
Figure 1: SUSE Telco Cloud architecture

SUSE Rancher Prime supplies unified orchestration and management across distributed edge sites. It enables centralized control, consistent policy enforcement, and zero-touch operations through declarative GitOps workflows and Cluster API (CAPI), allowing operators to manage hundreds of edge locations with a single operational model.

At the workload layer, OCUDU delivers AI-native, software-defined Central Unit (CU) and Distributed Unit (DU) network functions. Designed as a cloud-native implementation of the 5G RAN stack (supporting O-RAN Split 7.2), OCUDU brings intelligence directly into the RAN, incorporating native design elements for AI/ML-driven optimization, scheduling, and performance enhancement. This enables operators to run intelligent RAN workloads directly on the SUSE Telco Cloud platform with consistent, carrier-grade behavior. As a foundational component for AI-RAN, OCUDU allows seamless integration of real-time AI capabilities into the RAN stack, accelerating the transition toward intelligent, adaptive 5G and 6G networks.

Together, these components create a complete horizontal solution anchored in the Project Sylva reference architecture and delivered through SUSE Telco Cloud. By using Kubernetes as the interoperability layer where telco software converges, the stack fully decouples RAN software from proprietary hardware. This architecture directly addresses the fragmentation and lock-in challenges outlined earlier by providing operators with a standardized, portable, and consistent operating model. This solution eliminates the need for site-specific custom integrations while delivering carrier-grade performance at scale. It dramatically reduces deployment times from weeks to minutes and lowers CAPEX through hardware efficiency. Additionally, it enables true "Develop Once, Deploy Anywhere" portability.

4 Architecture overview and deployment

This reference architecture defines a single-node deployment designed for hardware validation, performance benchmarking, and resource sizing of AI-native RAN workloads. It integrates OCUDU’s gNB implementation with SUSE Telco Cloud, following Project Sylva principles for a consistent, cloud-native telco stack.

OCUDU on suse telco
Figure 2: Architecture Overview and Deployment

The architecture follows O-RAN Split 7.2, with all CU and DU functions consolidated in a single gNB pod running alongside an RU emulator. This configuration enables complete software-based testing of the DU-to-RU path over the Open Fronthaul interface without requiring physical radio hardware.

5 Product overview

5.1 SUSE Telco Cloud (SUSE Edge)

SUSE Edge 3.5 is an enterprise-grade platform purpose-built for edge computing and telecommunications workloads. It provides a complete infrastructure stack optimized for telco-specific requirements including real-time processing, deterministic latency, and hardware acceleration.

5.1.1 Core technology stack

  • SUSE Linux Micro RT: A real-time capable operating system based on SUSE Linux Micro, featuring the PREEMPT_RT kernel patch for microsecond-level latency guarantees. This OS is immutable, providing enhanced security and reliability through transactional updates.

  • RKE2 (Rancher Kubernetes Engine 2): A CNCF-certified Kubernetes distribution hardened for security and compliance. RKE2 focuses on ease of operations and includes embedded components like etcd and containerd.

  • Metal3: Kubernetes-native bare metal host management using the Cluster API provider for bare metal. Metal3 treats physical servers as cloud resources, enabling declarative infrastructure management through BMC (Baseboard Management Controller) interfaces.

  • Cluster API (CAPI): A Kubernetes sub-project providing declarative APIs to automate cluster lifecycle management. CAPI enables consistent cluster provisioning, upgrading, and scaling across different infrastructure providers.

  • SR-IOV Network Operator: Automates the discovery, configuration, and lifecycle management of SR-IOV network devices in Kubernetes clusters, enabling high-performance networking for CNF workloads.

5.1.2 Edge Image Builder

SUSE provides the Edge Image Builder (EIB), a tooling ecosystem that creates customized OS images containing:

  • Pre-installed packages (real-time kernel, DPDK, tuned profiles)

  • Embedded scripts for file system growth, performance tuning, SR-IOV automation

  • Network configurations and systemd units

  • Kubernetes manifests deployed at cluster bootstrap

The declarative image-building process ensures consistent, reproducible deployments across hardware fleets.

5.1.3 Key features for telco workloads

  • Real-time kernel (PREEMPT_RT): Provides deterministic task scheduling with sub-millisecond latency, critical for RAN processing where timing violations can cause call drops.

  • CPU isolation: Kernel parameters (isolcpus, nohz_full, rcu_nocbs) dedicate cores exclusively to workloads, preventing kernel interference.

  • Huge pages: 1 GB and 2 MB page support for DPDK applications, reducing TLB misses and improving memory access performance by up to 30%.

  • SR-IOV: Hardware-accelerated network virtualization bypassing the kernel network stack, achieving near-native NIC performance with CPU offload.

Directed network provisioning: Automated cluster deployment with advanced networking using nmstate for static IPs, VLANs, bonding, and dual-stack configurations.

5.2 OCUDU

OCUDU is a cloud-native implementation of 5G RAN components, providing deployment options for the gNB, CU, DU, CU-CP, and CU-UP. In this article, we focus on the gNB deployment variant, where all applications are combined into a single monolithic binary. OCUDU supports O-RAN Split 7.2, and Split 6 and Split 8. In this blog post, we use Split 7.2.

architecture
Figure 3: O-RAN Split 7.2

5.2.1 O-RAN Split 7.2

The diagram above shows how OCUDU maps the 5G RAN protocol stack onto O-RAN logical components. The blue area represents the OCUDU implementation, while the O-RU is shown as the external radio unit connected through the fronthaul interface.

In this reference architecture, Split 7.2 defines where the DU connects to the O-RAN Radio Unit over the O-RAN Open Fronthaul interface. OCUDU provides the CU and DU-side functionality shown in the blue area of the diagram, including O-CU-CP, O-CU-UP, O-DU-high, and O-DU-low. The O-RU sits outside OCUDU and exchanges fronthaul traffic with the DU using the Split 7.2 interface.

  • O-CU-CP: Provides the control-plane part of the CU, including RRC and PDCP-C. It connects to the 5G Core control plane over NG-C/N2, to the O-CU-UP over E1, to the O-DU over F1-C, and optionally to the near-RT RIC over E2.

  • O-CU-UP: Provides the user-plane part of the CU, including SDAP and PDCP-U. It connects to the 5G Core user plane over NG-U/N3 and to the O-DU over F1-U.

  • O-DU-high: Contains the higher DU layers shown in the diagram, including RLC and MAC.

  • O-DU-low: Contains the lower DU processing shown in the diagram. For Split 7.2, this is the OCUDU component that connects to the O-RU over the O-RAN Open Fronthaul interface.

  • O-RU: Represents the O-RAN Radio Unit. It sits outside OCUDU and connects to the DU over the Split 7.2 fronthaul interface.

The diagram also shows Split 6 and 8 as an alternative lower-layer split option. This blog post focuses on Split 7.2, where the DU-to-RU connection uses the O-RAN Open Fronthaul model.

5.2.2 OCUDU RAN workloads

ComponentPurposeSizing Guidance

ocudu-gnb

Runs the OCUDU gNB deployment variant. In this blog post, this includes the CU-CP, CU-UP, and DU functionality in a single monolithic application.

Size according to the selected RAN configuration. Bandwidth, number of cells, antenna configuration, MIMO layers, numerology, enabled features, and traffic profile all influence CPU, memory, hugepage, and network requirements.

ru-emulator

Provides an emulated O-RAN Radio Unit for lab and validation scenarios where physical RU hardware is not used.

Size according to the fronthaul configuration and the amount of generated or processed radio traffic. It can be co-located with the gNB for simple lab setups or placed on separate hardware for more realistic deployments.

linuxptp

Deploys linuxptp components used for clock synchronization in deployments where DU and RU timing must be aligned, such as multi-node or physical O-RU scenarios.

Lightweight compared to the RAN workload. Resource usage is usually minimal, but the configuration must match the selected NIC, PHC, and synchronization design.

5.2.3 Observability components

The observability stack is lightweight compared to the RAN workloads. For a minimal working example, InfluxDB3, Grafana, and Telegraf can run on a single Kubernetes CPU core with approximately 500 MB of RAM. Increase these resources when collecting more metrics, using shorter collection intervals, retaining data for longer periods, or serving more dashboard users.

ComponentPurposeSizing Guidance

InfluxDB3

Stores time-series metrics generated during the test, such as application, traffic, and RAN-related measurements.

Part of the minimal observability stack. Size according to metric volume, retention period, and whether persistent storage is required.

Grafana

Provides dashboards for visualizing OCUDU and deployment metrics.

Part of the minimal observability stack. Usually lightweight for lab usage; increase resources for more users, dashboards, or data sources.

Telegraf

Collects metrics from the OCUDU deployment and forwards them to the metrics database.

Part of the minimal observability stack. Size according to the number of collected metrics, collection interval, and buffering requirements.

Important
Important

Resource sizing principle:

Size the RAN workloads from the radio configuration first, then allocate observability resources based on the amount of telemetry you want to collect and retain.

5.2.4 Test mode capabilities

OCUDU test mode exercises the complete software stack without requiring real UEs or RUs. Depending on the test use case, OCUDU can be tested with a physical radio unit or with the radio side fully emulated in software. This makes it useful for both lab validation and performance testing before integrating physical RAN hardware.

In this reference architecture, we use the OCUDU RU emulator to fully exercise the OCUDU RAN stack and produce meaningful results in a controlled software-based environment.

Configuration parameters:

  • nof_ues: Number of emulated users.

  • rnti: Radio Network Temporary Identifier used for the emulated UE.

  • cqi: Channel Quality Indicator. A higher CQI allows the scheduler to select a higher modulation and coding scheme.

  • ri: Rank Indicator for the number of downlink MIMO layers. In this reference architecture we use 4x4 MIMO in downlink and a single layer in uplink.

  • pusch_active / pdsch_active: Enable uplink and downlink traffic generation.

Reference test configuration:

  • Downlink: 4x4 MIMO with QAM256.

  • Uplink: Single-layer in uplink.

  • TDD pattern: DDDDDDDSUU (7D1S2U). Test mode is enabled through the gNB configuration. The relevant test mode options are set directly inside the OCUDU gNB configuration before the workload is started. When the gNB and RU emulator are running, monitor both logs and metrics to validate the deployment.

Performance or configuration issues are usually visible in the application logs and telemetry. For example, incorrect radio configuration, fronthaul configuration problems, timing issues, or resource bottlenecks should be investigated by checking the OCUDU logs together with the exported metrics.

Warning
Warning

Test Mode Scope:

Test mode generates controlled test traffic for validating the OCUDU RAN stack and the underlying infrastructure. It is intended for RAN performance benchmarking, configuration validation, and troubleshooting. End-to-end behavior with real UEs, physical RF conditions, and a production 5G Core should be validated separately when those components are part of the target deployment.

6 Reference architecture

6.1 Deployment topology

Scenario 1: Single node deployment

This scenario co-locates the OCUDU gNB and the RU emulator on the same physical server. It is useful for lab validation because the DU and RU emulator can use the same clock source and therefore remain synchronized without additional PTP or SyncE setup.

In a real O-RAN Split 7.2 deployment, the DU node and the Radio Unit must be synchronized using PTP or SyncE. In this reference architecture, that external synchronization requirement does not apply because the RU emulator and DU run on the same host and use the same clock source.

Warning
Warning

NIC and clock source requirement:

The DU and RU emulator connection must use the same physical NIC. If different NICs are used, the deployment may rely on two different PHCs, and those clocks would also need to be synchronized. Keeping both sides on the same NIC avoids this additional synchronization requirement for the single-node scenario.

single node deploy
Figure 4: Single-Node Deployment
Important
Important

Critical Requirements for Single-Node Deployment:

  • Same VLAN: If VLANs are used both NIC ports need to be on the same VLAN. Layer-2 connectivity is sufficient for OFH packet exchange.

  • Intel E810 NIC: Recommended for timing precision and SR-IOV stability. The E810 (Columbiaville) family provides hardware timestamping and low jitter. While PTP synchronization works on many NICs, the E810 has been validated for this deployment. For dual-node deployments, use the E810-XXVDA4T or an external PTP Grandmaster (PTP GM).

  • MAC address consistency: The du_mac_addr in gNB configuration must match the VF MAC, and ru_mac_addr in RU configuration must match its VF MAC. Mismatches cause packet drops.

Scenario 2: Dual node deployment

This scenario separates the DU and RU onto different physical servers, simulating a real distributed deployment where the DU is centralized and RUs are at cell sites.

duel node deploy
Figure 5: Dual Node Deployment

Additional requirements for dual-node:

  • PTP synchronization: Both nodes must synchronize their system clocks using IEEE 1588v2 PTP (Precision Time Protocol). The E810-XXVDA4T variant provides sufficient PTP accuracy. Alternatively you can use a PTP Grandmaster (GM) of PTP class C.

  • Timing accuracy: OFH requires a mean error to be smaller than 20ns. Class C PTP hardware is required.

  • VLAN configuration: If using VLANs, configure them identically on both nodes. Uncomment vlan_tag_cp and vlan_tag_up in the configurations.

6.2 Hardware specifications

Flexibility Note: OCUDU can run on a wide range of hardware platforms, from small single-board computers (for example, Raspberry Pi) to large dual-socket servers with 256 cores per NUMA node. The application is designed for performance benchmarking and can adapt to virtually any Kubernetes-capable hardware. The specifications below represent a validated reference configuration for telco-grade performance testing.

ComponentPurposeSizing Guidance

CPU

40+ physical cores (Intel Xeon Scalable or equivalent) Scales from low-power ARM to high-core-count x86

Reference: 8 cores for system, 32+ cores isolated for OCUDU workloads. Adjust based on available hardware.

Memory

64 GB+ RAM Scales based on workload requirements

Reference: 40 GB for 1 GB hugepages, rest for OS and Kubernetes. Adjust hugepage allocation based on total memory.

NIC

SR-IOV capable NIC (25GbE recommended) Intel E810-XXVDA4/T validated

SR-IOV support required. Intel E810 provides hardware timestamping and has been validated. E810-XXVDA4T (or PTP GM) required for dual-node.

Storage

NVMe SSD (250 GB+)

OS installation, logs, InfluxDB3 persistence. Scale based on retention requirements.

BMC

Redfish-compatible BMC (for CAPI/Metal3)

Remote provisioning via Metal3. Examples: iDRAC, iLO, or equivalent with virtual media support.

Important
Important

Hardware compatibility notes:

  • Platform flexibility: OCUDU can benchmark performance on any Kubernetes-capable platform. Resource requirements scale with target throughput and cell count.

  • AVX-512 (Optional): The OCUDU AVX-512 image (ocudu_nightly_avx512) provides DSP optimizations for x86 platforms. Non-AVX-512 platforms can use alternative builds.

  • NUMA awareness: For multi-socket systems, pin workloads to a single NUMA node using Kubernetes topologyManagerPolicy: single-numa-node to minimize memory access latency.

  • TSC (x86): Ensure constant TSC (Time Stamp Counter) for DPDK timing on x86 platforms. Check /proc/cpuinfo for constant_tsc flag.

7 CAPI workflow and deployment

7.1 Management cluster architecture

A persistent management cluster provisions downstream or workload clusters. This separation provides operational flexibility and centralized lifecycle management.

management cluster
Figure 6: Management Cluster Architecture

Why this architecture?

  • Blast radius containment: Workload cluster failures do not affect management cluster stability.

  • Scalability: One management cluster can provision hundreds of edge clusters.

  • Upgrades: Upgrade workload clusters independently without disrupting management operations.

  • Multi-tenancy: Isolate different teams/applications into separate clusters with shared management.

7.2 Deployment Steps

Step 1: Bare metal host enrollment

Create a BareMetalHost custom resource to register physical servers with Metal3. This resource encapsulates BMC credentials, hardware identifiers, and provisioning state.

apiVersion: v1
kind: Secret
metadata:
  name: lab-sm1-credentials
type: Opaque
data:
  username: QURNSU4K          # Base64: ADMIN
  password: MTIzNA==          # Base64: 1234 (mock password for example)
---
apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
  name: lab-sm1
  labels:
    cluster-role: control-plane  # Used by Metal3MachineTemplate hostSelector
spec:
  online: true  # Power on the host
  bootMACAddress: 3C:EC:EF:DF:76:98  # PXE boot interface MAC
  rootDeviceHints:
    deviceName: /dev/nvme0n1  # Target disk for OS installation
  bmc:
    address: redfish-virtualmedia://10.168.204.22/redfish/v1/Systems/1/
    disableCertificateVerification: true  # Use in labs; enable certs in production
    credentialsName: lab-sm1-credentials  # Reference to Secret above

Field explanations:

  • bootMACAddress: Identifies the network interface for PXE boot. Must match the NIC configured for management network (not the SR-IOV data plane NIC).

  • rootDeviceHints: Selects the installation target disk. Alternatives: wwn, serialNumber, minSizeGigabytes. Use deviceName for predictable naming.

  • bmc.address: Redfish API endpoint. Format: redfish-virtualmedia://<BMC_IP>/redfish/v1/Systems/<SYSTEM_ID>/. Virtual media mounts the ISO remotely.

  • labels.cluster-role: Selector for Metal3MachineTemplate. Enables grouping hosts by role (control-plane vs. worker).

State transitions:

  • Registering: Metal3 authenticates to BMC and powers on the host.

  • Inspecting: Ironic introspects hardware (CPU count, memory, NICs, disks) via a ramdisk boot.

  • Available: Host is ready for provisioning. Remains in this state until claimed by a cluster.

  • Provisioning: OS image is written to disk via BMC virtual media or HTTP boot.

  • Provisioned: OS is installed, Ignition configurations applied, RKE2 cluster bootstrapped.

Important
Important

Troubleshooting BMH:

  • Check BMH status: kubectl get baremetalhosts -o wide

  • View provisioning events: kubectl describe baremetalhost lab-sm1

  • Ironic logs: kubectl logs -n baremetal-operator-system deploy/baremetal-operator-controller-manager

  • Common issues: incorrect BMC credentials, network firewall blocking Redfish, wrong boot MAC address

Step 2: CAPI cluster definition

The Cluster resource is the top-level abstraction representing a Kubernetes cluster. It references infrastructure-specific and control-plane implementations.

apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
  name: single-node-cluster2
  namespace: default
  labels:
    cluster-api.cattle.io/rancher-auto-import: "true"  # Auto-import to Rancher
spec:
  clusterNetwork:
    pods:
      cidrBlocks:
        - 192.168.0.0/18  # Pod CIDR: 16,384 IPs
    services:
      cidrBlocks:
        - 10.96.0.0/12  # Service CIDR: 1,048,576 IPs (standard K8s default)
  controlPlaneRef:
    apiVersion: controlplane.cluster.x-k8s.io/v1beta1
    kind: RKE2ControlPlane  # RKE2-specific control plane implementation
    name: single-node-cluster2
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: Metal3Cluster  # Bare metal infrastructure provider
    name: single-node-cluster2
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3Cluster
metadata:
  name: single-node-cluster2
  namespace: default
spec:
  controlPlaneEndpoint:
    host: 10.168.200.23  # Cluster API endpoint IP (node IP or VIP)
    port: 6443  # Kubernetes API server port
  noCloudProvider: true  # No cloud-controller-manager (bare metal)

Network configuration:

  • Pod CIDR: 192.168.0.0/18 provides 16,384 IP addresses for pods. Calico CNI assigns /26 blocks per node (64 IPs per node supports 256 nodes).

  • Service CIDR: 10.96.0.0/12 is the standard Kubernetes default, supporting ~1M ClusterIP services.

  • Control Plane Endpoint: In single-node deployments, use the node’s IP. In multi-node, use a VIP managed by MetalLB or keepalived.

Step 3: RKE2 control plane configuration

The RKE2ControlPlane defines Kubernetes version, CNI selection, and node-level customizations.

---
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: RKE2ControlPlane
metadata:
  name: single-node-cluster2
  namespace: default
spec:
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: Metal3MachineTemplate
    name: single-node-cluster2-controlplane
  replicas: 1  # Single-node cluster (no HA)
  version: v1.34.2+rke2r1  # RKE2 version (Kubernetes 1.34.2)
  rolloutStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxSurge: 0  # No surge in single-node (can't have 2 control planes)
  registrationMethod: "control-plane-endpoint"  # Nodes register using API endpoint
  serverConfig:
    cni: calico  # Calico CNI for pod networking
    cniMultusEnable: true  # Enable Multus for secondary networks (SR-IOV)
  preRKE2Commands:
    - modprobe vfio-pci enable_sriov=1 disable_idle_d3=1  # Load VFIO driver
  agentConfig:
    format: ignition
    additionalUserData:
      config: |
        variant: fcos
        version: 1.4.0
        storage:
          files:
            - path: /var/lib/rancher/rke2/server/manifests/ocudu-grafana.yaml
              # Content: Helm Chart for Grafana → Section 4.2
            - path: /var/lib/rancher/rke2/server/manifests/ocudu.yaml
              # Content: Helm Chart for ocudu-gnb → Section 4.2
            - path: /var/lib/rancher/rke2/server/manifests/ru-emulator.yaml
              # Content: Helm Chart for RU emulator → Section 4.3
            - path: /var/lib/rancher/rke2/server/manifests/sriov-operator.yaml
              # Content: Helm Chart for SR-IOV Operator → Section 5.2
            - path: /etc/rancher/rke2/config.yaml.d/99-z-additional-user-data-config.yaml
              # Content: RKE2 kubelet config → Section 6
            - path: /opt/sriov/sriov-auto-filler.sh
              # Content: SR-IOV VF creation script → Section 5.2
            - path: /opt/sriov/sriov-mac-override.sh
              # Content: VF MAC address override script → Section 5.2
            # ... additional ConfigMaps and NetworkAttachmentDefinitions
        systemd:
          units:
            - name: sriov-custom-auto-vfs.service
              # Content: Systemd unit for VF creation → Section 5.2
            - name: sriov-mac-override.service
              # Content: Systemd unit for MAC override → Section 5.2
        kernelArguments:
          shouldExist:
            - hugepagesz=1G hugepages=40
            - isolcpus=domain,nohz,managed_irq,8-39
            - nohz_full=8-39
            # ... complete kernel parameters → Section 6
  machineSelectorConfig:
    config:
      node-labels:
        - node.kubernetes.io/instance-type=baremetal

Critical settings explained:

  • version: RKE2 versions include Kubernetes version + RKE2 patch (for example, v1.34.2+rke2r1 = K8s 1.34.2 with RKE2 revision 1).

  • cniMultusEnable: true: Enables Multus meta-CNI plugin, allowing pods to attach to multiple networks. Required for SR-IOV secondary interfaces.

  • preRKE2Commands: Executed before RKE2 installation. Loads VFIO-PCI driver with SR-IOV enabled and D3 power state disabled (prevents NIC power-saving issues).

  • rolloutStrategy: Controls control-plane node upgrades. maxSurge: 0 prevents temporary dual control-planes (not possible in single-node).

  • agentConfig.additionalUserData: Contains Ignition configuration (FCOS format) that runs at first boot. The structure above shows all file paths, systemd units, and kernel parameters with clickable links to sections where each component’s content is detailed. Complete Ignition format explained in Section 4.1.

Important
Important

Why Calico + Multus?

  • Calico: Provides pod-to-pod networking, network policies, and BGP routing. Calico’s IPinIP or VXLAN encapsulation enables cross-node communication.

  • Multus: Allows pods to have multiple network interfaces. The primary interface (eth0) uses Calico for Kubernetes services; secondary interfaces (net1, net2) use SR-IOV for data plane traffic.

  • SR-IOV CNI: Multus delegates secondary interface creation to SR-IOV CNI, which assigns VFs to pods based on NetworkAttachmentDefinition resources.

Step 4: Metal3MachineTemplate Definition

The Metal3MachineTemplate defines the infrastructure-specific configuration for control plane machines, including host selection, image provisioning, and OS customization via Ignition.

---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3MachineTemplate
metadata:
  name: single-node-cluster2-controlplane
  namespace: default
spec:
  nodeReuse: false  # Do not reuse nodes after deprovisioning
  template:
    spec:
      automatedCleaningMode: disabled  # Skip disk wiping (faster reprovisioning)
      hostSelector:
        matchLabels:
          cluster-role: control-plane  # Matches BareMetalHost label
      image:
        checksum: http://10.168.200.30:8080/eibimage-35-62-rt-telco.raw.sha256
        checksumType: sha256
        format: raw
        url: http://10.168.200.30:8080/eibimage-35-62-rt-telco.raw
      agentConfig:
        additionalUserData:
          name: single-node-cluster2-additional-user-data
          namespace: default

Key configuration points:

  • hostSelector.matchLabels: Selects BareMetalHosts with cluster-role: control-plane label. This enables grouping hosts by role (control-plane vs. worker).

  • image.url: HTTP-accessible raw disk image built with Edge Image Builder (EIB). Must include RT kernel, RKE2, and telco packages.

  • image.checksum: SHA256 checksum for image verification during provisioning. Prevents corrupted image deployments.

  • automatedCleaningMode: disabled: Skips automated disk wiping between provisions. Enable for production to ensure clean state.

  • agentConfig.additionalUserData: References a Secret containing Ignition configuration for OS customization (kernel parameters, systemd services, files).

Important
Important

Image server requirements:

The image URL must be accessible from the target bare metal host’s provisioning network. Typically served via HTTP from the management cluster or a dedicated artifact server. The checksum file should contain only the SHA256 hash value.

8 Configuration deep dive

8.1 Ignition configuration framework

The agentConfig.additionalUserData section uses Ignition format (Fedora CoreOS-style declarative configuration). Ignition runs early in the boot process, before RKE2 starts, to configure the OS and inject files.

Ignition capabilities:

  • File injection: Write Kubernetes manifests, systemd units, scripts to specific paths

  • Systemd units: Create, enable, and start services

  • Kernel parameters: Add boot arguments for performance tuning

  • User management: Create users, set SSH keys

8.2 OCUDU gNB helm chart configuration

The gNB is deployed through RKE2’s built-in HelmChart CRD, which applies the Helm release automatically during cluster bootstrap. For this proof of concept, we use the default OCUDU Split 7.2 profile for the OCUDU gNB.

apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
  name: ocudu-gnb
  namespace: kube-system  # Deployed in kube-system, pods run in targetNamespace
spec:
  chart: oci://registry.gitlab.com/ocudu/ocudu_elements/ocudu_helm/ocudu-gnb
  targetNamespace: srs  # Namespace for workload pods
  version: 3.3.2  # Helm chart version
  createNamespace: true
  valuesContent: |-
    image:
      repository: registry.gitlab.com/ocudu/ocudu/ocudu_nightly_avx512
      tag: 20260227_2c67c805  # Nightly build with AVX-512 optimizations

    resources:
      limits:
        cpu: 24  # Exclusive CPUs (cpuManagerPolicy: static)
        memory: 16Gi
        hugepages-1Gi: 2Gi  # 2GB of 1GB hugepages for DPDK
        rancher.io/odu: 1  # SR-IOV VF resource
      requests:
        cpu: 24  # Guaranteed allocation
        memory: 16Gi
        hugepages-1Gi: 2Gi
        rancher.io/odu: 1

    sriovConfig:
      enabled: true
      extendedResourceName: "rancher.io/odu"  # Matches SR-IOV ConfigMap

    network:
      hostNetwork: false  # Use pod networking (required for SR-IOV)

    securityContext:
      allowPrivilegeEscalation: false
      capabilities:
        add:
          - SYS_NICE
          - IPC_LOCK
      privileged: false

Resource allocation explained:

  • CPU: 24 cores with limits == requests triggers Kubernetes static CPU manager, guaranteeing exclusive core allocation. Cores are pinned from the isolated set (8-39).

  • Memory: 16Gi standard RAM. DPDK applications allocate most memory from hugepages, not regular RAM.

  • Huge pages: 2Gi of 1GB pages (hugepages-1Gi). DPDK mmap()s these for zero-copy packet buffers, reducing TLB misses.

  • SR-IOV: rancher.io/odu: 1 requests one VF from the odu resource pool. The SR-IOV device plugin advertises VF availability to the kubelet.

8.2.1 Security context

The OCUDU gNB container does not need to run as a privileged container. Instead, the deployment uses a minimum-privilege security context that grants only the Linux capabilities required by the workload.

securityContext:
        allowPrivilegeEscalation: true
        privileged: false
        capabilities:
            drop: ["ALL"]
            add:
            - SYS_NICE
            - IPC_LOCK

The required capabilities are:

  • SYS_NICE: Allows the process to set scheduling priorities required for real-time and performance-sensitive processing.

  • IPC_LOCK: Allows the process to lock memory and avoid paging for memory used by the workload, including hugepage-backed memory.

This minimum-privilege setup expects the container image to include the required file capabilities on the gNB binary, for example cap_sys_nice and cap_ipc_lock. The Kubernetes node also needs containerd configured with device_ownership_from_security_context = true so that device ownership is derived from the container security context.

8.2.2 SR-IOV networking

SR-IOV must be enabled for this deployment. The gNB uses SR-IOV Virtual Functions to access high-performance network interfaces without relying on the host network namespace.

sriovConfig:
        enabled: true

This requires the SR-IOV device plugin to be deployed in the Kubernetes cluster and the relevant physical NICs to be configured to expose Virtual Functions.

8.2.3 Host network and networkPolicy

For this deployment, hostNetwork must remain disabled. When a pod uses hostNetwork: true, it joins the host network namespace and bypasses Kubernetes NetworkPolicy enforcement. Keeping hostNetwork disabled allows the deployment to use SR-IOV interfaces while still preserving Kubernetes network isolation controls.

network:
        hostNetwork: false

        networkPolicy:
        enabled: false

NetworkPolicy can be enabled when the cluster CNI supports networking.k8s.io/v1 policies. It is only effective when hostNetwork is set to false.

8.3 gNB configuration file (gnb-config.yml)

The gNB configuration embedded in the Helm Chart defines cell parameters, OFH timing, test mode settings, and logging.

# Open Fronthaul Configuration
ru_ofh:
  # Timing windows
  t1a_max_cp_dl: 500  # Max time before slot for DL C-Plane TX
  t1a_min_cp_dl: 390  # Min time before slot for DL C-Plane TX
  t1a_max_cp_ul: 450  # Max time before slot for UL C-Plane TX
  t1a_min_cp_ul: 285  # Min time before slot for UL C-Plane TX
  t1a_max_up: 300  # Max time before slot for U-Plane TX
  t1a_min_up: 150  # Min time before slot for U-Plane TX
  ta4_max: 350  # Max time after slot for U-Plane RX
  ta4_min: 80   # Min time after slot for U-Plane RX

  # IQ compression (reduces fronthaul bandwidth by ~40%)
  compr_method_ul: bfp  # Block Floating Point
  compr_bitwidth_ul: 9  # 9-bit samples (vs. 16-bit uncompressed)
  compr_method_dl: bfp
  compr_bitwidth_dl: 9
  compr_method_prach: bfp
  compr_bitwidth_prach: 9

  # Static compression headers (avoids per-packet overhead)
  enable_ul_static_compr_hdr: true
  enable_dl_static_compr_hdr: true

  # IQ scaling factor (amplitude adjustment)
  iq_scaling: 12.5

  # Alert on missing RU frames (debugging)
  warn_unreceived_ru_frames: always

  # Cell-specific OFH settings
  cells:
    - network_interface: 0000:53:11.0  # PCI address of SR-IOV VF (auto-detected)
      du_mac_addr: 00:11:22:33:00:11  # DU MAC (must match VF MAC)
      ru_mac_addr: 00:11:22:33:00:01  # RU MAC (must match RU emulator VF MAC)
      prach_port_id: "[4,5]"  # OFH ports for PRACH (random access)
      dl_port_id: "[0,1,2,3]"  # OFH ports for DL (4 antenna ports)
      ul_port_id: "[0]"  # OFH ports for UL (1 antenna port)

# DPDK Configuration
hal:
  eal_args: "--lcores (0-1)@(0-11)"  # Bind DPDK control threads to cores 0-1,
                                      # allow worker threads on cores 0-11 (from isolated set)

# Cell Radio Parameters
cell_cfg:
  dl_arfcn: 643452  # Downlink ARFCN (band 78, 3.7 GHz center frequency)
  band: 78  # 5G NR band 78 (3.3-3.8 GHz TDD)
  channel_bandwidth_MHz: 100  # 100 MHz channel
  common_scs: 30  # Subcarrier spacing (30 kHz for FR1)
  plmn: "00101"  # PLMN ID (MCC=001, MNC=01, test network)
  tac: 7  # Tracking Area Code
  pci: 1  # Physical Cell ID
  nof_antennas_dl: 4  # 4 TX antennas (4x1 MIMO)
  nof_antennas_ul: 1  # 1 RX antenna

  # TDD pattern (10ms period)
  tdd_ul_dl_cfg:
    dl_ul_tx_period: 10  # 10ms frame
    nof_dl_slots: 7  # 7 DL slots
    nof_dl_symbols: 6  # + 6 DL symbols in special slot
    nof_ul_slots: 2  # 2 UL slots
    nof_ul_symbols: 4  # + 4 UL symbols in special slot
    # Effective DL:UL ratio ~75:25

  # Modulation and Coding Schemes
  pdsch:
    mcs_table: qam256  # Enable 256-QAM (MCS 0-28)
  pusch:
    mcs_table: qam256

# Test Mode (UE emulation)
test_mode:
  test_ue:
    rnti: 0x44  # Radio Network Temporary Identifier
    ri: 4  # Rank Indicator (4 MIMO layers)
    cqi: 15  # Channel Quality Indicator (15 = best)
    nof_ues: 1  # Number of emulated UEs
    pusch_active: true  # Enable uplink traffic
    pdsch_active: true  # Enable downlink traffic

8.3.1 OFH timing parameters

The t1a and ta4 windows define when packets are valid. Packets arriving outside these windows are dropped as "early" or "late". These values are tuned empirically:

  • t1a_max_cp_dl: 500: DU sends Control-Plane DL packets 390-500 microseconds before the slot boundary.

  • ta4_max: 350: DU expects User-Plane UL packets within 80-350 microseconds after the slot boundary.

  • Misconfigurations cause timing violations logged as RX_EARLY, RX_LATE, TX_EARLY, TX_LATE.

8.3.2 IQ compression

Block Floating Point (BFP) compression reduces OFH bandwidth from ~25 Gbps to ~15 Gbps for 100MHz:

  • 9-bit samples: Each I/Q sample is 9 bits (vs. 16-bit uncompressed)

  • Shared exponent: BFP groups samples and shares a single exponent, trading precision for bandwidth

8.3.3 TDD pattern

The 7:2 DL:UL slot ratio is optimized for high downlink throughput (streaming, video):

  • DL: 7 slots + 6 symbols = 7.6 ms of DL per 10 ms frame (76%)

  • UL: 2 slots + 4 symbols = 2.4 ms of UL per 10 ms frame (24%)

  • Special slot: Contains guard period (GP) for TX/RX switching

8.3.4 MIMO configuration

4x1 MIMO (4 TX antennas, 1 RX) with RI=4 enables 4-layer spatial multiplexing:

  • Peak throughput: 4 layers × 100 MHz × 30 kHz SCS × QAM256 ≈ 1.4 Gbps theoretical

  • Measured: ~1.4 Gbps in test mode (overhead from PDCCH, DMRS, guard bands)

9 Network configuration

9.1 SR-IOV architecture

Single Root I/O Virtualization (SR-IOV) is a hardware-based virtualization technology that creates virtual functions (VFs) from a physical NIC. Each VF appears as an independent PCIe device, enabling near-native performance without hypervisor overhead.

9.1.1 How SR-IOV works

sriov architecture
Figure 7: SR-IOV Architecture

The benefits of SR-IOV include:

  • Performance: DPDK bypasses kernel, achieving line-rate throughput with minimal CPU usage

  • Isolation: Each VF has dedicated queues, preventing noisy neighbor interference

  • Hardware offload: TX/RX checksum, segmentation offload, RSS (Receive Side Scaling)

  • Low latency: Direct DMA to userspace memory (DPDK), avoiding context switches

9.2 SR-IOV configuration

SUSE Telco Cloud automates SR-IOV setup using a custom ConfigMap consumed by a systemd service.

apiVersion: v1
kind: ConfigMap
metadata:
  name: sriov-custom-auto-config
  namespace: sriov-network-operator
data:
  config.json: |
    [
       {
         "resourceName": "odu",              # Kubernetes resource name
         "interface": "ens6f1np1",           # Physical function interface
         "pfname": "ens6f1np1",              # PF name (for iproute2 commands)
         "driver": "vfio-pci",               # VF driver (DPDK-compatible)
         "numVFsToCreate": 1                 # Number of VFs to create
       },
       {
         "resourceName": "oru",
         "interface": "ens6f0np0",
         "pfname": "ens6f0np0",
         "driver": "vfio-pci",
         "numVFsToCreate": 1
       }
    ]

Configuration fields:

FieldDescriptionExample

resourceName

Extended resource advertised to kubelet as rancher.io/resourceName

odu → rancher.io/odu

interface

Physical function network interface name

ens6f1np1 (biosdevname naming)

pfname

PF name for VF creation commands (echo N > /sys/class/net/pfname/device/sriov_numvfs)

ens6f1np1

driver

VF driver to bind. Options: vfio-pci (DPDK), iavf (kernel), igb_uio (legacy)

vfio-pci for OCUDU

numVFsToCreate

Number of virtual functions to create from this PF

1 (one pod per PF)

9.2.1 Systemd service sriov-custom-auto-vfs.service

This service reads the ConfigMap and creates VFs:

[Unit]
Description=SRIOV Custom Auto VF Creation
Wants=network-online.target rke2-server.target
After=network.target network-online.target rke2-server.target

[Service]
User=root
Type=forking
TimeoutStartSec=1800  # 30 minutes timeout
ExecStart=/bin/sh -c "while ! /var/lib/rancher/rke2/bin/kubectl \
  --kubeconfig=/etc/rancher/rke2/rke2.yaml \
  wait --for condition=ready nodes --timeout=30m --all ; \
  do sleep 10 ; done"
ExecStartPost=/bin/sh -c "/opt/sriov/sriov-auto-filler.sh"
RemainAfterExit=yes
KillMode=process

[Install]
WantedBy=multi-user.target

The execution flow is:

  1. Wait for RKE2 cluster to be ready (all nodes in Ready state)

  2. Execute /opt/sriov/sriov-auto-filler.sh which:

    • Reads ConfigMap via kubectl

    • Creates VFs: echo 1 > /sys/class/net/ens6f1np1/device/sriov_numvfs

    • Binds VFs to vfio-pci driver: dpdk-devbind.py --bind=vfio-pci 0000:53:11.0

    • Advertises resources to kubelet

9.3 MAC address override service

Critical for OCUDU: The gNB and RU emulator configurations hardcode specific MAC addresses, but SR-IOV VF MAC addresses are randomized by default. It is critical for OCUDU to override this.

[Unit]
Description=SRIOV MAC Address Override
Wants=sriov-custom-auto-vfs.service
After=sriov-custom-auto-vfs.service

[Service]
Type=oneshot
User=root
# Wait for VF 0 to appear on ens6f1np1, then set MAC
ExecStart=/bin/sh -c "while ! ip link show ens6f1np1 | grep -q 'vf 0'; \
  do sleep 2; done; \
  ip link set ens6f1np1 vf 0 mac 00:11:22:33:00:11"

# Wait for VF 0 to appear on ens6f0np0, then set MAC
ExecStart=/bin/sh -c "while ! ip link show ens6f0np0 | grep -q 'vf 0'; \
  do sleep 2; done; \
  ip link set ens6f0np0 vf 0 mac 00:11:22:33:00:01"

RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
Warning
Warning
  • Packet Filtering: OFH uses Ethernet layer-2 addressing. The gNB sends packets to ru_mac_addr (00:11:22:33:00:01), and the RU sends to du_mac_addr (00:11:22:33:00:11).

  • DPDK VFIO: When VFs are bound to vfio-pci, the kernel network stack does not manage them. MAC addresses must be set via the PF before binding.

  • Failure Mode: Mismatched MACs cause 100% packet drops. gNB logs show "Missed incoming User-Plane uplink messages" continuously.

Verify as follows:

# Check VF creation
ip link show ens6f1np1
# Output should show: vf 0 MAC 00:11:22:33:00:11

# Check VF PCI address
lspci | grep -i virtual
# 0000:53:11.0 Ethernet controller: Intel Corporation Ethernet Virtual Function 700 Series

# Verify VFIO binding
dpdk-devbind.py --status
# 0000:53:11.0 'Ethernet Virtual Function 700 Series' drv=vfio-pci unused=iavf

# Check Kubernetes node capacity
kubectl describe node | grep -A5 "Capacity"
# Should show: rancher.io/odu: 1, rancher.io/oru: 1

9.4 Network attachment definition (Multus)

Multus requires NetworkAttachmentDefinition resources to attach secondary interfaces to pods. The SR-IOV CNI uses these definitions.

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: odu-network
  namespace: srs
spec:
  config: '{
    "cniVersion": "0.3.1",
    "type": "sriov",
    "name": "odu-network",
    "ipam": {
      "type": "host-local",
      "subnet": "192.168.10.0/24",
      "rangeStart": "192.168.10.10",
      "rangeEnd": "192.168.10.20",
      "routes": [{
        "dst": "0.0.0.0/0"
      }],
      "gateway": "192.168.10.1"
    }
  }'
Note
Note

For DPDK applications, IPAM is often irrelevant since packets bypass the kernel IP stack. The SR-IOV CNI primarily handles VF assignment and passthrough.

10 Performance tuning

10.1 Kernel parameters

Kernel boot parameters configure the OS for real-time, low-latency operation. These are defined in the CAPI manifest’s kernel_arguments.should_exist section.

kernelArguments:
  shouldExist:
    - idle=poll
    - mce=off
    - hugepagesz=1G hugepages=40
    - hugepagesz=2M hugepages=0
    - default_hugepagesz=1G
    - irqaffinity=0-7
    - isolcpus=domain,nohz,managed_irq,8-39
    - nohz_full=8-39
    - rcu_nocbs=8-39
    - rcu_nocb_poll
    - nosoftlockup
    - nowatchdog
    - nohz=on
    - nmi_watchdog=0
    - skew_tick=1
    - quiet
    - rcupdate.rcu_cpu_stall_suppress=1
    - rcupdate.rcu_expedited=1
    - rcupdate.rcu_normal_after_boot=1
    - rcupdate.rcu_task_stall_timeout=0

Parameter explanations:

ParameterValuePurpose

intel_iommu

on

Enable Intel IOMMU for VT-d (device passthrough, DMA remapping)

iommu

pt

Passthrough mode: devices not in VM bypass IOMMU translation (lower overhead)

idle

poll

Disable CPU idle states (C-states). CPUs spin-wait instead of sleeping, reducing wakeup latency from ~100 μs to 0

hugepagesz

1G

Default hugepage size (1 GB pages for DPDK)

hugepages

40

Allocate 40 × 1 GB = 40 GB of hugepages at boot

default_hugepagesz

1G

Default size for new hugepage allocations

irqaffinity

0-7

Route hardware interrupts (IRQs) to cores 0-7. Prevents interrupts on isolated cores.

isolcpus

domain,nohz,managed_irq,8-39

Isolate cores 8-39 from scheduler, tickless operation, and managed IRQs

nohz_full

8-39

Disable periodic timer ticks on cores 8-39 (adaptive-tick mode). Reduces jitter from 1000 Hz to 0 Hz when running single task.

rcu_nocbs

8-39

Offload RCU callbacks from cores 8-39 to helper threads on cores 0-7. RCU is Read-Copy-Update synchronization mechanism.

nosoftlockup

-

Disable soft lockup detector (prevents false positives on polling cores)

nowatchdog

-

Disable NMI watchdog (reduces jitter from periodic checks)

nohz

on

Enable dynamic tick (tickless kernel)

rcutree.kthread_prio

99

Set RCU kernel threads to real-time priority 99 (highest)

Tip
Tip
  • Cores 0-7 (System Cores): Handle OS tasks, Kubernetes components, system daemons, interrupts. These cores remain under normal scheduler control.

  • Cores 8-39 (Isolated Cores): Dedicated to OCUDU workloads. The kernel scheduler does not place tasks here unless explicitly pinned (via cgroups/cpusets). Timer ticks are disabled (adaptive-tick), and RCU callbacks are offloaded, minimizing OS interference.

  • Result: Isolated cores achieve deterministic performance with <10 μs jitter, suitable for real-time RAN processing.

10.2 CPU partitioning (tuned profile)

The cpu-partitioning tuned profile optimizes isolated cores further by adjusting scheduler, memory, and power settings.

[Unit]
        Description=cpu-partitioning

        [Service]
        Type=oneshot
        User=root
        # Write isolated cores to tuned config file
        ExecStart=/bin/sh -c "echo isolated_cores=8-39 > /etc/tuned/cpu-partitioning-variables.conf"
        # Activate cpu-partitioning profile
        ExecStartPost=/bin/sh -c "tuned-adm profile cpu-partitioning"
        # Enable tuned to persist across reboots
        ExecStartPost=/bin/sh -c "systemctl enable tuned.service"

        [Install]
        WantedBy=multi-user.target

Tuned optimizations:

  • CPU governor: Set to performance (fixed maximum frequency, no power scaling)

  • IRQ balancing: Disable irqbalance service on isolated cores

  • Scheduler: Reduce scheduling quantum on system cores to improve responsiveness

  • Memory: Disable zone reclaim on NUMA nodes

Verification:

# Check active tuned profile
        tuned-adm active
        # Output: Current active profile: cpu-partitioning

        # Verify isolated cores
        cat /sys/devices/system/cpu/isolated
        # Output: 8-39

        # Check CPU governor (should be 'performance' on all cores)
        cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
        # Output: performance (repeated for each core)

10.3 Kubelet configuration

Kubelet configuration enforces CPU and memory topology policies.

apiVersion: kubelet.config.k8s.io/v1beta1
        kind: KubeletConfiguration
        cpuManagerPolicy: static              # Enable static CPU manager
        reservedSystemCPUs: 0-7               # Reserve cores 0-7 for kubelet and system
        topologyManagerPolicy: single-numa-node  # Enforce single-NUMA allocation

These policy options are explained in the following sections.

cpuManagerPolicy: static

Static CPU manager allocates exclusive CPUs to Guaranteed pods (those with limits == requests for CPU).

  • Behavior: When a pod requests CPU resources, kubelet assigns specific cores from the non-reserved set (8-39) using cpusets.

  • Isolation: No other pods or system processes can use these cores.

  • Requirement: Pod must be QoS class "Guaranteed" (all containers have CPU/memory limits == requests).

reservedSystemCPUs: 0-7

Reserves cores 0-7 for:

  • kubelet daemon

  • Container runtime (containerd)

  • System daemons (sshd, systemd, etc.)

  • Kubernetes system pods (kube-proxy, calico, multus) This prevents system load from interfering with workload cores.

topologyManagerPolicy: single-numa-node

Enforces that all resources for a pod (CPUs, memory, devices) come from a single NUMA node.

  • Why: Cross-NUMA memory access has 2-3x higher latency (~100ns local vs. ~200ns remote).

  • Benefit: For DPDK applications, keeping CPU, hugepages, and NIC on the same NUMA node maximizes throughput and minimizes jitter.

  • Failure mode: If resources span NUMA nodes, pod admission is rejected.

10.4 DPDK core binding

DPDK’s EAL (Environment Abstraction Layer) arguments control which CPU cores are used by DPDK threads. When SR-IOV is enabled, the exact CPU cores assigned to the gNB pod are not known until runtime. Kubernetes assigns those cores dynamically, and the allocation can change between deployments.

To avoid manually reconfiguring the EAL arguments for every deployment, the gNB entrypoint script updates the core list at startup. It reads the CPU allocation available to the container and replaces the configured core values with the cores assigned to the pod at runtime. The entrypoint script can only replace the lcores correctly if you follow this format: --lcores (lcores)@(physical_cores). Keep the lcores braket set to (0-1) and the second one (0-11) or similar. The same applies for the RU emulator.

# gNB DPDK configuration
        hal:
        eal_args: "--lcores (0-1)@(0-11)"

        # RU Emulator DPDK configuration
        dpdk:
        eal_args: "--lcores (0-1)@(0-11)"

Syntax: --lcores (lcores)@(physical_cores)

  • lcores: DPDK internal thread IDs

  • Physical cores: Linux CPU numbers (from isolated set) Example: (0-1)@(0-11) means:

  • DPDK logical core 0 can run on any of physical cores 0-11

  • DPDK logical core 1 can run on any of physical cores 0-11

  • DPDK scheduler distributes work threads across these cores

11 Validation and monitoring

11.1 Deployment verification

  1. Apply BMH and CAPI Manifests.

    # Apply Bare Metal Host
            kubectl apply -f bmh-sm1-ocudu.yaml
    
            # Verify BMH state (should transition to Available)
            kubectl get baremetalhosts -o wide
            # NAME      STATE         ONLINE   BMC                 HARDWARE_PROFILE   ERROR
            # lab-sm1   provisioned   true     10.168.204.22       unknown
    
            # Apply CAPI cluster
            kubectl apply -f capi-sm1-ocudu.yaml
    
            # Monitor cluster creation
            kubectl get cluster -w
            # NAME                   PHASE         AGE
            # single-node-cluster2   Provisioned   5m
    
            kubectl get rke2controlplane -w
            # NAME                   READY   AGE
            # single-node-cluster2   true    10m
  2. Access Downstream Cluster.

    # Get kubeconfig from management cluster
            clusterctl get kubeconfig single-node-cluster2 > kubeconfig-ocudu.yaml
            export KUBECONFIG=kubeconfig-ocudu.yaml
    
            # Verify nodes are Ready
            kubectl get nodes
            # NAME          STATUS   ROLES                       AGE   VERSION
            # lab-sm1       Ready    control-plane,etcd,master   15m   v1.34.2+rke2r1
    
            # Check SR-IOV operator status
            kubectl get pods -n sriov-network-operator
            # sriov-network-operator-xxxxx   1/1   Running
            # sriov-device-plugin-xxxxx      1/1   Running
    
            # Verify SR-IOV VFs created
            kubectl get sriovnetworknodestates -n sriov-network-operator -o yaml
            # Should show VFs for ens6f0np0 and ens6f1np1
  3. Verify OCUDU Pods.

    # Check pods in srs namespace
            kubectl get pods -n srs -o wide
            # NAME                           READY   STATUS    NODE
            # ocudu-gnb-xxxxx                1/1     Running   lab-sm1
            # ru-emulator-xxxxx              1/1     Running   lab-sm1
            # grafana-ocudu-xxxxx            1/1     Running   lab-sm1
            # influxdb3-xxxxx                1/1     Running   lab-sm1
            # telegraf-xxxxx                 1/1     Running   lab-sm1
    
            # Check resource allocation
            kubectl describe pod ocudu-gnb-xxxxx -n srs | grep -A10 "Limits"
            # Limits:
            #   cpu:                24
            #   hugepages-1Gi:      2Gi
            #   memory:             16Gi
            #   rancher.io/odu:     1
    
            # Check gNB logs (expect "Cell started" message)
            kubectl logs -n srs ocudu-gnb-xxxxx --tail=50
            # Look for: "Cell pci=1, bw=100 MHz, dl_arfcn=643452 (n78), dl_freq=3725.04 MHz, ul_freq=3725.04 MHz"
    
            # Check RU emulator logs
            kubectl logs -n srs ru-emulator-xxxxx --tail=50
            # Look for: "RU emulator started successfully"

11.2 Performance validation

  1. Expected throughput

    For 1 cell, 1 UE, 100MHz TDD, 4x1 MIMO, QAM256:

    • Target DL: ~1.4 Gbps

    • Target UL: ~100 Mbps

  2. Grafana dashboard access

    # Get node IP
            NODE_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}')
    
            # Access Grafana
            echo "Grafana URL: http://${NODE_IP}:30001"
            # Default credentials: admin / admin1234
    
            # Navigate to:
            # - Dashboard → {ocudu} Metrics (throughput, MCS, BLER)
            # - Dashboard → OFH Metrics (RX_ON_TIME, RX_EARLY, RX_LATE)
  3. Key metrics to monitor

LayerMetricExpected ValueMeaning

PHY

DL throughput

~1.4 Gbps

Downlink data rate

PHY

UL throughput

~100 Mbps

Uplink data rate (lower due to TDD ratio)

MAC

DL MCS

27-28

Modulation and Coding Scheme (28 = QAM256, rate 0.93)

MAC

UL MCS

27-28

Uplink MCS

MAC

BLER

< 0.1%

Block Error Rate (retransmission rate)

OFH

RX_ON_TIME_PCT

> 99%

Percentage of packets received within timing window

OFH

RX_EARLY_PCT

< 1%

Packets arriving before t1a_min (timing misconfiguration)

OFH

RX_LATE_PCT

< 1%

Packets arriving after t1a_max

OFH

RX_ERR_DROP_PCT

0%

Dropped packets (MAC mismatch, CRC errors)

11.3 7.3 Log-Based Validation (Parsers)

The repository includes Python parsers to extract KPIs from logs and compare against thresholds.

  1. gNB log parser

    # Collect gNB logs from hostPath persistence
            kubectl exec -n srs ocudu-gnb-xxxxx -- cat /tmp/gnb.log > /tmp/gnb.log
    
            # Run parser
            cd parser
            python3 gnb_log_parser.py \
            --input /tmp/gnb.log \
            --json-out /tmp/gnb.json \
            --md-out /tmp/gnb.md
    
            # Output: Markdown report with:
            # - Cell configuration summary
            # - UE attachment events
            # - Throughput samples
            # - Error/warning counts
  2. RU emulator log parser

    # Collect RU logs
            kubectl exec -n srs ru-emulator-xxxxx -- cat /tmp/ru_emu.log > /tmp/ru_emu.log
    
            # Run parser with threshold validation
            python3 ru_log_parser.py \
            --input /tmp/ru_emu.log \
            --thresholds fixtures/ru_thresholds.yaml \
            --json-out /tmp/ru.json \
            --md-out /tmp/ru.md
    
            # Thresholds example (fixtures/ru_thresholds.yaml):
            # rx_on_time_pct_min: 99.0
            # rx_early_pct_max: 1.0
            # rx_late_pct_max: 1.0
            # rx_err_drop_pct_max: 0.1
  3. InfluxDB3 KPI parser

    # Port-forward InfluxDB3 service
            kubectl port-forward -n srs svc/influxdb3 8081:8081 &
    
            # Run parser (queries time-series data via SQL)
            python3 influx_parser.py \
            --host http://localhost:8081 \
            --database srsran \
            --token fake-token-1234567890abcdef \
            --start 2026-05-05T10:00:00Z \
            --end 2026-05-05T10:10:00Z \
            --metrics fixtures/ocudu_metrics.yaml \
            --thresholds fixtures/ocudu_thresholds.yaml \
            --json-out /tmp/influx_summary.json \
            --md-out /tmp/influx_summary.md
    
            # Parser queries metrics like:
            # SELECT mean(dl_throughput) FROM srsran WHERE time >= ... AND time <= ...
            # Validates against thresholds and generates pass/fail report

12 Conclusion and next steps

This reference architecture demonstrates how the OCUDU RAN stack can be deployed on SUSE Telco Cloud for hardware validation and RAN workload sizing. The measured resource requirements serve as key input for planning and sizing production deployments. The setup functions as a validation environment that confirms whether the underlying platform delivers sufficient performance and correct configuration for a chosen RAN profile.

The deployment validates several key infrastructure capabilities required for carrier-grade Open RAN:

  • Declarative provisioning using CAPI and Metal3 to build the cluster through an infrastructure-as-code workflow.

  • High-performance networking using SR-IOV Virtual Functions and DPDK for direct, low-overhead packet processing.

  • Real-time readiness using the PREEMPT_RT kernel, CPU isolation, hugepages, and tuned profiles to reduce jitter and improve determinism.

  • O-RAN Split 7.2 validation by exercising the DU-to-RU path through the O-RAN Open Fronthaul interface using the RU emulator.

  • Comprehensive observability through logs, metrics, and dashboards to identify configuration issues, resource bottlenecks, timing problems, and performance limits.

In the single-node scenario, the OCUDU gNB and RU emulator run on the same host. This makes the setup particularly effective for validating CPU allocation, memory configuration, hugepages, SR-IOV device assignment, DPDK configuration, and overall platform readiness without requiring a separate physical RU.

The same validation approach can be adapted to different scenarios, including smaller functional tests, larger benchmark systems, dual-node DU/RU deployments, or multi-cell configurations. The critical consideration is that the RAN configuration and hardware profile must be evaluated together. Factors such as bandwidth, MIMO layers, antenna configuration, traffic model, and enabled features directly determine the required compute, memory, and I/O capacity.

By combining SUSE Telco Cloud’s robust, Sylva-compliant infrastructure with the OCUDU AI-native RAN stack, operators gain a practical path to overcome ecosystem fragmentation. This joint solution delivers standardized operations, reduced deployment complexity, lower infrastructure costs, and the flexibility to scale AI-native 5G and 6G services across diverse edge environments.

Ready to get started? Contact the SUSE Telco Cloud team today to schedule a dedicated technical workshop, review the OCUDU Getting Started Guide, or initiate your own validation deployment with OCUDU RAN on SUSE Telco Cloud.

14 GNU Free Documentation License

Copyright © 2000, 2001, 2002 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.

0. PREAMBLE

The purpose of this License is to make a manual, textbook, or other functional and useful document "free" in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.

This License is a kind of "copyleft", which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.

We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.

1. APPLICABILITY AND DEFINITIONS

This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The "Document", below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as "you". You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law.

A "Modified Version" of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.

A "Secondary Section" is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document’s overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.

The "Invariant Sections" are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none.

The "Cover Texts" are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words.

A "Transparent" copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not "Transparent" is called "Opaque".

Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only.

The "Title Page" means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, "Title Page" means the text near the most prominent appearance of the work’s title, preceding the beginning of the body of the text.

A section "Entitled XYZ" means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as "Acknowledgements", "Dedications", "Endorsements", or "History".) To "Preserve the Title" of such a section when you modify the Document means that it remains a section "Entitled XYZ" according to this definition.

The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License.

2. VERBATIM COPYING

You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.

You may also lend copies, under the same conditions stated above, and you may publicly display copies.

3. COPYING IN QUANTITY

If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document’s license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.

If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.

If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.

It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.

4. MODIFICATIONS

You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:

  1. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.

  2. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement.

  3. State on the Title page the name of the publisher of the Modified Version, as the publisher.

  4. Preserve all the copyright notices of the Document.

  5. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.

  6. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.

  7. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document’s license notice.

  8. Include an unaltered copy of this License.

  9. Preserve the section Entitled "History", Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled "History" in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.

  10. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the "History" section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.

  11. For any section Entitled "Acknowledgements" or "Dedications", Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.

  12. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.

  13. Delete any section Entitled "Endorsements". Such a section may not be included in the Modified Version.

  14. Do not retitle any existing section to be Entitled "Endorsements" or to conflict in title with any Invariant Section.

  15. Preserve any Warranty Disclaimers.

If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version’s license notice. These titles must be distinct from any other section titles.

You may add a section Entitled "Endorsements", provided it contains nothing but endorsements of your Modified Version by various parties—​for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.

You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.

The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.

5. COMBINING DOCUMENTS

You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers.

The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.

In the combination, you must combine any sections Entitled "History" in the various original documents, forming one section Entitled "History"; likewise combine any sections Entitled "Acknowledgements", and any sections Entitled "Dedications". You must delete all sections Entitled "Endorsements".

6. COLLECTIONS OF DOCUMENTS

You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.

You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.

7. AGGREGATION WITH INDEPENDENT WORKS

A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an "aggregate" if the copyright resulting from the compilation is not used to limit the legal rights of the compilation’s users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document.

If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document’s Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate.

8. TRANSLATION

Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail.

If a section in the Document is Entitled "Acknowledgements", "Dedications", or "History", the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title.

9. TERMINATION

You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

10. FUTURE REVISIONS OF THIS LICENSE

The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/.

Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation.

ADDENDUM: How to use this License for your documents

Copyright (c) YEAR YOUR NAME.
   Permission is granted to copy, distribute and/or modify this document
   under the terms of the GNU Free Documentation License, Version 1.2
   or any later version published by the Free Software Foundation;
   with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
   A copy of the license is included in the section entitled “GNU
   Free Documentation License”.

If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the “ with…​Texts.” line with this:

with the Invariant Sections being LIST THEIR TITLES, with the
   Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.

If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation.

If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.