Linux 網絡: netdevsi
netdevsim
,Netwoking Device Simulator,網絡設備模擬器。
netdevsim
就是用來模擬網絡設備的,其實它是 Linux 裏的一種網絡設備驅動;可以用來測試一些網絡功能,比如 tc
、tc-bpf
、XDP
。
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 裏。
- t.Run()[2]
所以,使用 netns 時,需要避免使用 t.Run()
。
小結
在 Go 的單元測試裏使用 netdevsim
時,需要注意以下幾點:
-
不同的單元測試需要使用不同的
netdevsim
ID 來創建netdevsim
設備,以免互相干擾; -
使用
ethtool -i [DEV]
來判斷一個網絡設備是不是netdevsim
設備; -
使用 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