Linux 網絡: netdevsi

netdevsim,Netwoking Device Simulator,網絡設備模擬器。

netdevsim 就是用來模擬網絡設備的,其實它是 Linux 裏的一種網絡設備驅動;可以用來測試一些網絡功能,比如 tctc-bpfXDP

netdevsim ID

創建 netdevsim 設備:echo "[ID] [PORT_COUNT] [NUM_QUEUES]" > /sys/bus/netdevsim/new_device.。不能通過 ip link add dev [NAME] type netdevsim 來創建。

銷燬 netdevsim 設備:echo "[ID]" > /sys/bus/netdevsim/del_device。不能通過 ip link del dev [NAME] 來銷燬。

也就是,不同 ID 可用來創建互不干擾的 netdevsim 設備。

netdevsim 設備類型

netdevsim 設備的類型當然是 netdevsim

不過,在代碼裏,該怎麼判斷一個網絡設備是 netdevsim 呢?

# ls -l /sys/class/net/
total 0
lrwxrwxrwx 1 root root    0 Jun 22 11:39 eni11np1 -> ../../devices/netdevsim11/net/eni11np1/
lrwxrwxrwx 1 root root    0 Jun 22 11:39 eni11np2 -> ../../devices/netdevsim11/net/eni11np2/

可以通過 readlink /sys/class/net/[DEV] 的方式來判斷。

不過,在 netns 裏就不一定有用了。

真實且穩定的判斷方式:

# ethtool -i eni11np1
driver: netdevsim
version: 5.15.0-18-generic
firmware-version:
expansion-rom-version:
bus-info: netdevsim11
supports-statistics: no
supports-test: no
supports-eeprom-access: no
supports-register-dump: no
supports-priv-flags: no

就是判斷設備的驅動是不是 netdevsim 就行了。

netdevsim 與 Go 單元測試

在 Go 的單元測試裏使用 netdevsim 踩坑了。

其實踩坑的地方不在 netdevsim,而是單元測試上。

我創建一個 netns 用來隔離不同單元測試實例,並且會 runtime.LockOSThread();然後在 netns 裏創建 netdevsim 網絡設備用來測試 tc 規則。

但卻沒認識到 t.Run() 會起一個新的 goroutine,而不是當前 goroutine;導致,t.Run() 的單測代碼並沒有跑在創建的 netns 裏。

所以,使用 netns 時,需要避免使用 t.Run()

小結

在 Go 的單元測試裏使用 netdevsim 時,需要注意以下幾點:

  1. 不同的單元測試需要使用不同的 netdevsim ID 來創建 netdevsim 設備,以免互相干擾;

  2. 使用 ethtool -i [DEV] 來判斷一個網絡設備是不是 netdevsim 設備;

  3. 使用 netns 來創建 netdevsim 設備時,需要避免使用 t.Run()

參考資料

[1]

GitHub netdevsim: https://github.com/torvalds/linux/tree/master/drivers/net/netdevsim

[2]

t.Run(): https://pkg.go.dev/testing#T.Run

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/NuD97-ivNcV3cplx3-OJ1Q