# 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

### 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.

```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