學習 Linux Kernel Network NS (namespace) - ianchen0119/Introduce-to-5GC GitHub Wiki
如果讀者有使用過像是 Docker 之類的 Container Engine,可能會知道 Docker 在 Linux 上實作 Docker Network 使用了 Network namespace 的技巧。 然而,本篇文章之所以會談 Network nameapce 並不是要介紹容器化技術,而是向大家分享 free5GC 是如何利用這項技術做出一些 procedural testing 的!
名詞解說
什麼是 namespace?
許多程式語言、開發工具都有提供 namespace 的功能,像是:
- Kubernetes 提供 Namespace 區隔不同的資源
- C++ 提供 Namespace 避免變數、函數名稱的重複以及混淆
Linux 同樣提供 Network namespace 讓開發者將網路環境獨立出來以便測試,本章會以 free5GC 的測試腳本示範 Network namespace 的威力!
什麼是 bridge?
Linux bridge 可以讓兩個不相同的網段相連,當兩個分開的網段使用橋接器相連後,彼此之間就能夠互相溝通了! 其工作原理是利用 Data link layer 的封包轉發,當電腦收到資料時,會根據它的 MAC 訊息進行轉發、廣播或是丟棄。
什麼是 veth?
veth(Virtual Ethernet)是 Linux kernel 提供的虛擬網路裝置,它的兩端可以在不同的 Network namespace 上面工作。利用這個特性,我們可以使主機與容器端之間的網路相通。
進入正題
本篇文章會以 free5GC v3.1.1 的 test_multiUPF 腳本做介紹,帶大家理解 free5GC 如何利用 network ns 在一台 Host 上面啟動多個 UPF:
# Setup bridge
sudo ip link add veth0 type veth peer name br-veth0
sudo ip link set veth0 up
sudo ip addr add 10.200.200.1/24 dev veth0
sudo ip addr add 10.200.200.2/24 dev veth0
sudo ip link add free5gc-br type bridge
sudo ip link set free5gc-br up
sudo ip link set br-veth0 up
sudo ip link set br-veth0 master free5gc-br
sudo iptables -I FORWARD 1 -j ACCEPT
sudo ip link add veth0 type veth peer name br-veth0
表示新增一對類型為veth
的裝置到 link layer 上,其中一個裝置的名稱為veth0
、另一個為br-veth0
。sudo ip link set veth0 up
喚醒veth0
裝置。sudo ip addr add 10.200.200.1/24 dev veth0
為vet0
新增 ip 位址。sudo ip link add free5gc-br type bridge
表示新增一個類型為bridge
的裝置到 link layer 上,該裝置的名稱為free5gc-br
。sudo ip link set free5gc-br up
用於啟動我們剛剛新增的free5gc-br
裝置。sudo ip link set br-veth0 up
喚醒br-veth0
裝置。sudo ip link set br-veth0 master free5gc-br
設定br-veth0
為 slave、free5gc-br
為 master。
腳本的上半部分建立了 veth0
裝置,並且為它增加了 ip 10.200.200.2
,目的是讓 N3 Interface 可以跟 RAN 的網路環境隔離,這個設定在 free5GC 的其他測試腳本中也都可以看到。
而下半部分則是因為該腳本有多個 UPF,為了讓每一個 UPF 的網路環境區隔起來,所以做了類似於上半部的設定:
# Setup network namespace
for i in $(seq -f "%02g" 1 $UPF_NUM); do
sudo ip netns add "${UPFNS}${i}"
sudo ip link add "veth${i}" type veth peer name "br-veth${i}"
sudo ip link set "br-veth${i}" up
sudo ip link set "veth${i}" netns "${UPFNS}${i}"
sudo ip netns exec "${UPFNS}${i}" ip link set lo up
sudo ip netns exec "${UPFNS}${i}" ip link set "veth${i}" up
sudo ip netns exec "${UPFNS}${i}" ip addr add "10.200.200.1${i}/24" dev "veth${i}"
sudo ip link set "br-veth${i}" master free5gc-br
if [ ${DUMP_NS} ]; then
sudo ip netns exec "${UPFNS}${i}" tcpdump -i any -w "${UPFNS}${i}.pcap" &
sleep 1
TCPDUMP_PID_[${i}]=$(sudo ip netns pids "${UPFNS}${i}")
fi
cd NFs/upf/build && sudo -E ip netns exec "${UPFNS}${i}" ./bin/free5gc-upfd -c "${CONF_DIR}/multiUPF/upfcfg${i}.yaml" &
sleep 1
done
sudo ip netns add "${UPFNS}${i}"
為每一個 UPF 建立 network namespace。sudo ip link add "veth${i}" type veth peer name "br-veth${i}"
設定一對 veth 裝置。sudo ip link set "veth${i}" netns "${UPFNS}${i}"
將veth{i}
移動到對應的 namespace 下方。sudo ip netns exec "${UPFNS}${i}" ip link set "veth${i}" up
喚醒 namespace 下的veth{i}
裝置。sudo ip netns exec "${UPFNS}${i}" ip addr add "10.200.200.1${i}/24" dev "veth${i}"
為veth{i}
裝置新增 ip 位址,做到這裡 local 端與新建立的 namespace 下的 veth 裝置就可以使用 ping 打通了。sudo ip link set "br-veth${i}" master free5gc-br
設定 master 與 slave。sudo ip netns exec "${UPFNS}${i}" tcpdump -i any -w "${UPFNS}${i}.pcap" & sleep 1
使用tcpdump
錄製 UPF 的封包。sudo -E ip netns exec "${UPFNS}${i}" ./bin/upf -c "${CONF_DIR}/multiUPF/upfcfg${i}.yaml" & sleep 1
於新建立的 namespace 下執行 upf。
相關專案介紹:netns5g
前陣子在 review free5gc 專案
的 Issue 時,看到了有一位熱心的貢獻者參考了測試腳本中 Linux NS 的應用,開發了一套專案可以讓我們在同一台 Host 執行 free5GC 與 UERANSIM。
netns5g 在使用上也非常簡單,首先將專案 clone 到本地端:
git clone https://github.com/konradkar2/netns5g.git
接著執行兩份腳本:
# 環境設定
sudo ./env-init.sh
# 部署 free5GC
sudo ./deploy.sh
部署核心網路後,我們將 UERANSIM 在剛剛建立好的 network namespace 上啟動:
sudo ip netns exec gnb <UERANSIM gNB executable> -c ./config/free5gc-gnb.yaml
sudo ip netns exec ue <UERANSIM ue executable> -c ./config/free5gc-ue.yaml
<UERANSIM gNB executable>
與<UERANSIM ue executable>
請帶上編譯後的執行檔案路徑。
最後,等到 GTP-U Tunnel 建立完成,我們就可以透過核心網路連線至 Internet 了!
sudo ip netns exec ue ping 10.0.130.1 -I uesimtun0
總結
要了解核心網路是如何運作,除了閱讀原始程式碼,也可以觀察測試腳本甚至是每一個 NF 的設定檔,以本篇文章來說,我們透過觀察 test_multiUPF
腳本學習了 ip-link
tool 的使用技巧,也了解到 free5GC 是利用這個方式讓基本的流程測試可以在同一台 host 上進行。