0%

Linux switchdev

在 Linux 内核 4.0 前,Linux 内核并没有对硬件交换模块的支持,尽管在 bridge 实现了一个软网桥,所有的交换都是通过 CPU 实现的,但是并没有实现对于真正硬件交换机的支持,通用接口层面一直没有合理的解决方案。Linux 4.0 引入了 switchdev 框架,全称是 Ethernet switch device driver model,它代表一类具有「交换」能力芯片的多网口设备的抽象,使得内核可以将「交换」功能 offload 到硬件上。

技术背景

switchdev 模型之前,开发者如果想要将交换功能从内核 offload 到自己硬件交换模块上,在内核并没有一个统一的模型,需要自己去实现复杂的驱动代码。

记得去年的时候,我曾经拿到过一块交换板,可以直接插在主板的PCI-E上,当时必须使用厂商特定的驱动程序以及配合VLAN技术才能将其用起来。其实很多的交换机可能都采用了Linux作为管理平面和控制平面,然后配置自己的定制硬件和定制驱动来使用。

我曾经想过一种办法用Netfilter技术实现对硬件交换模块的支持,但是,CPU还是要被中断的,整个流程是CPU将数据包拉到bridge或者IP层,然后再交回硬件…正确的方式是根本不用中断CPU,完全通过硬件来转发数据包,只有数据和本地协议栈相关的时候,才中断CPU。而这个思路,意味着你必须重写驱动。

总之,没有一个统一的接口,这就意味着如果你自己想设计一块交换板,没有比较好的标准可循,即便有,可能你也要自己编写或者复制粘贴大量的驱动代码,这将严重影响研发效率。

switchdev 框架如下图所示,硬件交换模块是一个具有「交换」能力的多网口设备抽象。其中每个网口就是一个 port,在 switchdev 框架中被注册成 net_device。除此之外,内核中自带了一个rocker driver,演示了一个实际的设备驱动的实现

框架模型

下图展示了 switchdev 模型,硬件是专门用于交换的 ASIC 芯片,硬件每个交换的 port 都对应在 switch driver 里面实现的网口设备。在 switch driver 初始化过程中,驱动会遍历每个硬件交换机端口,同时申请和创建一个 net_device ,一般被称作 port netdev

port netdev 是硬件交换机端口的软件抽象,也是构建更高层级 bridgesbondsVLANstunnels 和 L3 routers 的基础。使用标准的 netdev 工具,比如 iproute2ethtool 等,port netdev 也可以给用户提供关于 swich port 的 PHY link state 和 I/O statistics 相关数据。

There is (currently) no higher-level kernel object for the switch beyond the
port netdevs. All of the switchdev driver ops are netdev ops or switchdev ops.

A switch management port is outside the scope of the switchdev driver model.
Typically, the management port is not participating in offloaded data plane and
is loaded with a different driver, such as a NIC driver, on the management port
device.

注意,理想化的实现中,OpenFlow 控制器可以直接将流表注入到设备中,从而指导设备直接进行数据包交换。流表的内容超级复杂,不是本文的目标,但是相信在后一个内核版本中会出现相关的Document。采用了硬件交换模块的Linux BOX和原来的截然不同了,它更像是一个高端的专业网络设备,类似Cisco那样的。它看起来就是下面的样子:

参考资料