AI-Native Disaggregated RAN #
Project Sylva Reference Architecture with SUSE Telco Cloud and OCUDU RAN Stack
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.
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.
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.
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.
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 #
| Component | Purpose | Sizing 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.
| Component | Purpose | Sizing 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. |
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.
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.
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.
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_addrin gNB configuration must match the VF MAC, andru_mac_addrin 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.
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_cpandvlan_tag_upin 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.
| Component | Purpose | Sizing 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. |
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-nodeto minimize memory access latency.TSC (x86): Ensure constant TSC (Time Stamp Counter) for DPDK timing on x86 platforms. Check
/proc/cpuinfoforconstant_tscflag.
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.
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 aboveField 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.
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/18provides 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/12is 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=baremetalCritical 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.
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: defaultKey configuration points:
hostSelector.matchLabels: Selects BareMetalHosts withcluster-role: control-planelabel. 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).
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: falseResource allocation explained:
CPU: 24 cores with
limits == requeststriggers 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: 1requests one VF from theoduresource 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_LOCKThe 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: trueThis 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: falseNetworkPolicy 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 traffic8.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 #
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:
| Field | Description | Example |
|---|---|---|
| Extended resource advertised to kubelet as rancher.io/resourceName | odu → rancher.io/odu |
| Physical function network interface name | ens6f1np1 (biosdevname naming) |
| PF name for VF creation commands (echo N > /sys/class/net/pfname/device/sriov_numvfs) | ens6f1np1 |
| VF driver to bind. Options: | vfio-pci for OCUDU |
| 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:
Wait for RKE2 cluster to be ready (all nodes in Ready state)
Execute
/opt/sriov/sriov-auto-filler.shwhich:Reads ConfigMap via kubectl
Creates VFs:
echo 1 > /sys/class/net/ens6f1np1/device/sriov_numvfsBinds VFs to vfio-pci driver:
dpdk-devbind.py --bind=vfio-pci 0000:53:11.0Advertises 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
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 todu_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"
}
}'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=0Parameter explanations:
| Parameter | Value | Purpose |
|---|---|---|
| on | Enable Intel IOMMU for VT-d (device passthrough, DMA remapping) |
| pt | Passthrough mode: devices not in VM bypass IOMMU translation (lower overhead) |
| poll | Disable CPU idle states (C-states). CPUs spin-wait instead of sleeping, reducing wakeup latency from ~100 μs to 0 |
| 1G | Default hugepage size (1 GB pages for DPDK) |
| 40 | Allocate 40 × 1 GB = 40 GB of hugepages at boot |
| 1G | Default size for new hugepage allocations |
| 0-7 | Route hardware interrupts (IRQs) to cores 0-7. Prevents interrupts on isolated cores. |
| domain,nohz,managed_irq,8-39 | Isolate cores 8-39 from scheduler, tickless operation, and managed IRQs |
| 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. |
| 8-39 | Offload RCU callbacks from cores 8-39 to helper threads on cores 0-7. RCU is Read-Copy-Update synchronization mechanism. |
| - | Disable soft lockup detector (prevents false positives on polling cores) |
| - | Disable NMI watchdog (reduces jitter from periodic checks) |
| on | Enable dynamic tick (tickless kernel) |
| 99 | Set RCU kernel threads to real-time priority 99 (highest) |
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.targetTuned 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 allocationThese policy options are explained in the following sections.
- cpuManagerPolicy: static
Static CPU manager allocates exclusive CPUs to Guaranteed pods (those with
limits == requestsfor 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 #
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 10mAccess 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 ens6f1np1Verify 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 #
Expected throughput
For 1 cell, 1 UE, 100MHz TDD, 4x1 MIMO, QAM256:
Target DL: ~1.4 Gbps
Target UL: ~100 Mbps
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)Key metrics to monitor
| Layer | Metric | Expected Value | Meaning |
|---|---|---|---|
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.
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 countsRU 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.1InfluxDB3 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.
13 Legal notice #
Copyright © 2006–2026 SUSE LLC and contributors. All rights reserved.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or (at your option) version 1.3; with the Invariant Section being this copyright notice and license. A copy of the license version 1.2 is included in the section entitled "GNU Free Documentation License".
SUSE, the SUSE logo and YaST are registered trademarks of SUSE LLC in the United States and other countries. For SUSE trademarks, see https://www.suse.com/company/legal/.
Linux is a registered trademark of Linus Torvalds. All other names or trademarks mentioned in this document may be trademarks or registered trademarks of their respective owners.
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.
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:
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.
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.
State on the Title page the name of the publisher of the Modified Version, as the publisher.
Preserve all the copyright notices of the Document.
Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.
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.
Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document’s license notice.
Include an unaltered copy of this License.
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.
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.
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.
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.
Delete any section Entitled "Endorsements". Such a section may not be included in the Modified Version.
Do not retitle any existing section to be Entitled "Endorsements" or to conflict in title with any Invariant Section.
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.

