---
# System prepended metadata

title: 'SA: OAI CU on VM & OSC O-DU High on bare metal'
tags: [oai, osc]

---

# SA: OAI CU on VM & OSC O-DU High on bare metal
###### tags: `oai` `osc`

[toc]

## Goal
:::info
Build up OAI CU on VM.
:::

## Environment
### Architecture
![](https://i.imgur.com/Hr12B3r.png)

### System and Equipment
**Hardware Requirement**
- Machine(Host): 2 servers:
    - CU server:
        - CPU: Intel(R) Xeon(R) Gold 6226R CPU @ 2.90GHz x 8
        - RAM: 16GB
        - Disk: 256GB
        - NICs: 1
    - DU server:
        - CPU: Intel® Xeon(R) Silver 4210 CPU @ 2.20GHz x 40
        - RAM: 100GB
        - Disk: 800GB
        - NICs: 1
- Router/Switch: 1

**Software Requirement**
- gNB: O-DU (branch "master", commit "9940b26") (Ubuntu 18.04) - Server 1: bare metal
- gNB: OAI CU (branch "develop", commit "3be77c09b5") (Ubuntu 18.04) - Server 2: VM
- Linux 64-bit machine
- 5.4.0-105-generic kernel
- Beyond GCC version 4.6.3
:::spoiler IP address
== OAI CU ==
----- OAI CU: 192.168.222.247

== O-DU ==
----- OSC O-DU High: 140.118.122.125
----- OSC O-DU Low: None
:::

## Software Installation and Deployment
### Prerequisite
Build up VM based on [Openstack Microstack](https://hackmd.io/dhng8FNHTgeA5Szm8wOhFQ).

Clone repository.
```shell=
git clone https://github.com/ferlinda/bmwlab_tony_cu_du.git
```
- OAI CU
    Install needed packages for OAI CU.
    ```shell=
    cd bmwlab_tony_cu_du/oai_cu
    source oaienv
    cd cmake_targets
    ./build_oai -I
    ```
- OSC O-DU High
    Install necessary libraries and clone code to build & compile OSC O-DU High
    Update newest package.
    ```shell=
    sudo apt-get update -y

    ## If you can't use `ifconfig`, run below command to install tools.
    sudo apt install net-tools -y
    ```
    Install necessary libraries to build & compile OSC O-DU High.
    ```shell=
    ## GCC, make sure your GCC version is 4.6.3 or above for compiling, and install it if necessary.
    gcc --version
    ## Install GCC by below command
    sudo apt-get install -y build-essential

    ## LKSCTP
    sudo apt-get install -y libsctp-dev

    ## PCAP 
    sudo apt-get install -y libpcap-dev
    ```

### Compilation
- OAI CU
    Build up the OAI binary.
    :::warning
    In my testing case, I use compile OAI with UE simulator for testing.
    :::
    ```shell=
    cd bmwlab_tony_cu_du/oai_cu/cmake_targets
    ./build_oai --gNB --nrUE -w SIMU
    ```
    Enable OAI CU to decode F1 Setup Request from OSC O-DU High and re-compile again.
    ```shell=
    cd bmwlab_tony_cu_du/oai_cu/cmake_targets
    ./f1ap_codec_mod.sh
    ./build_oai --gNB
    ```
- OSC O-DU High
    Check the options of compilation of OSC O-DU High.
    ```shell=
    ## Navigate to Build folder
    cd bmwlab_tony_cu_du/osc_odu_high/build/odu

    ## List the options
    make help
    ```
    You will see following options for reference.
    ![](https://i.imgur.com/Rpa8mbO.png)
    ```shell=
    ## format to compile binary
    make <node/clean_node> PHY=<none/INTEL_L1> PHY_MODE=<none/TIMER> MACHINE=<BIT64/BIT32> MODE=<FDD/TDD>
    ```
    :::warning
    In my testing case, I compile OSC O-DU High without O-DU Low integration and O1 interface enabled.
    :::
    * Go to build folder and clean up if you are not first time to compile
        * FDD mode
        ``` shell=
        ##Clean binaries
        make clean_odu MACHINE=BIT64 MODE=FDD
        make clean_cu NODE=TEST_STUB MACHINE=BIT64 MODE=FDD
        ```
        * TDD mode
        ``` shell=
        ##Clean binaries
        make clean_odu MACHINE=BIT64 MODE=TDD
        make clean_cu NODE=TEST_STUB MACHINE=BIT64 MODE=TDD
        ```
    * Compile binaries according to your requirement
        * FDD mode
        ``` shell=
        ##Compilation
        make odu MACHINE=BIT64 MODE=FDD
        make cu_stub NODE=TEST_STUB MACHINE=BIT64 MODE=FDD
        ```
        * TDD mode
        ``` shell=
        ##Compilation
        make odu MACHINE=BIT64 MODE=TDD
        make cu_stub NODE=TEST_STUB MACHINE=BIT64 MODE=TDD
        ```

## Setup Environment
Bind public IP with interface, make sure that the IP exists as following example.
```shell=
bmwlab@bmwlab-DL380:~$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens1f0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 98:f2:b3:23:82:34 brd ff:ff:ff:ff:ff:ff
    altname enp18s0f0
    inet 140.118.122.128/24 brd 140.118.122.255 scope global noprefixroute ens1f0
       valid_lft forever preferred_lft forever
    inet6 fe80::7b34:9c85:e6a:2577/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
```

Set up iptables of CU server as following example.
```shell=
bmwlab@bmwlab-DL380:~$ sudo iptables -t nat -A PREROUTING -p sctp -i ens1f0 --dport 38472 -j DNAT --to-destination 10.20.20.117:38472
```

Check the setting.
```shell=
bmwlab@bmwlab-DL380:~$ sudo iptables -t nat -L -n -v --line-numbers

Chain PREROUTING (policy ACCEPT 17 packets, 3624 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 DNAT       tcp  --  ens1f3 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:4001 to:10.20.20.131:22
2        0     0 DNAT       tcp  --  ens1f3 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:4002 to:10.20.20.117:22
3        5   320 DNAT       tcp  --  ens1f2 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:4001 to:10.20.20.131:22
4        2   120 DNAT       tcp  --  ens1f0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:4002 to:10.20.20.117:22
5        4   256 DNAT       tcp  --  ens1f2 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:4002 to:10.20.20.117:22
6        0     0 DNAT       sctp --  ens1f0 *       0.0.0.0/0            0.0.0.0/0            sctp dpt:4002 to:10.20.20.117:22
7        0     0 DNAT       sctp --  ens1f0 *       0.0.0.0/0            0.0.0.0/0            sctp dpt:38472 to:10.20.20.117:38472

Chain INPUT (policy ACCEPT 4 packets, 291 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 1 packets, 82 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1      281 21557 MASQUERADE  all  --  *      *       10.20.20.0/24       !10.20.20.0/24       
2    10808  762K MASQUERADE  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
```

## Run & Test
Make sure that the firewalls of other hosts do not work, otherwise, they could not detect VM.
```shell=
[oai@ee703-2-ip125 ~]$ firewall-cmd --state
Authorization failed.
    Make sure polkit agent is running or run the application as superuser.

[oai@ee703-2-ip125 ~]$ sudo firewall-cmd --state
running

[oai@ee703-2-ip125 ~]$ sudo systemctl stop firewalld

[oai@ee703-2-ip125 ~]$ sudo firewall-cmd --state
not running
```

Use `sctp_test` to verify the connection works.
```shell=
[oai@ee703-2-ip125 ~]sctp_test -H 140.118.122.125 -P 38472 -l
local:addr=140.118.122.125, port=38472, family=2
seed = 1653901031

Starting tests...
	socket(SOCK_SEQPACKET, IPPROTO_SCTP)  ->  sk=3
	bind(sk=3, [a:140.118.122.125,p:38472])  --  attempt 1/10
	listen(sk=3,backlog=100)
Server: Receiving packets.
	recvmsg(sk=3) Notification: SCTP_ASSOC_CHANGE(COMMUNICATION_UP)
		(assoc_change: state=0, error=0, instr=10 outstr=10)
	recvmsg(sk=3) Data 1 bytes. First 1 bytes: <empty> text[0]=0
	recvmsg(sk=3) Data 1 bytes. First 1 bytes: <empty> text[0]=0
	  SNDRCV(stream=0 ssn=0 tsn=2002140444 flags=0x1 ppid=1527157092
cumtsn=2002140444
	recvmsg(sk=3) Data 1 bytes. First 1 bytes: <empty> text[0]=0
	  SNDRCV(stream=0 ssn=0 tsn=2002140445 flags=0x1 ppid=446821785
cumtsn=2002140445
	recvmsg(sk=3) Data 1 bytes. First 1 bytes: <empty> text[0]=0
	  SNDRCV(stream=0 ssn=0 tsn=2002140446 flags=0x1 ppid=402740451
cumtsn=2002140446
	recvmsg(sk=3) Data 1 bytes. First 1 bytes: <empty> text[0]=0
	  SNDRCV(stream=0 ssn=0 tsn=2002140447 flags=0x1 ppid=61414386
cumtsn=2002140447
	recvmsg(sk=3) Data 1 bytes. First 1 bytes: <empty> text[0]=0
	  SNDRCV(stream=0 ssn=0 tsn=2002140448 flags=0x1 ppid=1375294203
cumtsn=2002140448
	recvmsg(sk=3) Data 1 bytes. First 1 bytes: <empty> text[0]=0
	  SNDRCV(stream=0 ssn=0 tsn=2002140449 flags=0x1 ppid=1521055343
cumtsn=2002140449
	recvmsg(sk=3) Data 1 bytes. First 1 bytes: <empty> text[0]=0
	  SNDRCV(stream=0 ssn=0 tsn=2002140450 flags=0x1 ppid=2077565134
cumtsn=2002140450
```

Running OAI CU on VM side.
```shell=
ubuntu@oai-cu:~$ sudo RFSIMULATOR=server ./nr-softmodem --rfsim --sa -O /home/ubuntu/config/gNB_SA_CU_with_remote_DU.con
...
[F1AP]   Starting F1AP at CU
[F1AP]   F1AP_CU_SCTP_REQ(create socket)
[ITTI]   Created Posix thread TASK_CU_F1
'
[SCTP]   sctp_bindx: Cannot assign requested address:99
[SCTP]   Failed to create new SCTP listener
'
[ITTI]   Created Posix thread TASK_GTPV1_U
[GTPU]   Initializing UDP for local address CI_GNB_IP_ADDR with port 2152
NFAPI MODE:MONOLITHIC
START MAIN THREADS
RC.nb_nr_L1_inst:0
wait_gNBs()
Waiting for gNB L1 instances to all get configured ... sleeping 50ms (nb_nr_sL1_inst 0)
[GTPU]   getaddrinfo error: Temporary failure in name resolution
[GTPU]   cant create GTP-U instance
[GTPU]   Created gtpu instance id: -1
...
```

Running OSC O-DU High.
```shell=
[oai@ee703-2-ip125 ~]sudo ./odu
...
Creating thread here /home/bmwlab/l2/src/mt/mt_ss.c 3596

Set priority 99

Creating thread here /home/bmwlab/l2/src/mt/mt_ss.c 3596

INFO   -->  DU_APP : DU APP created and registered    to 1 sys task

DEBUG   -->  EGTP : Initializing
INFO   -->  DU_APP : EGTP created and registered     to 2 sys task

DEBUG  -->  SCTP : Initializing
INFO   -->  DU_APP : SCTP TAPA task created and registered to 5 sys task
INFO   -->  DU_APP : RLC DL and MAC TAPA task created and registered to    3 sys task
INFO   -->  DU_APP : RLC UL TAPA task created and registered to    4 sys task
INFO   -->  DU_APP : LWR MAC TAPA task created and registered to 6 sys task
...
```

https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed/-/tree/master/docker-compose