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 呢?

1
2
3
4
# 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 里就不一定有用了。

真实且稳定的判断方式:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 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()