Linux内核最近跃进到了4.x时代,初看没啥大的动作,但是对于我而言,最令人兴奋的还是它对硬交换模块的支持。这也是为全面迎合SDN做好准备的第一步。
Linux上的路由与交换
Linux诞生于网络,天生对网络拥有全面且强大的支持,即便再复杂的协议,再封闭的技术,几乎都可以找到对应的Linux实现。然而这并不是说Linux网络就天下无敌了,它存在很多不合理的地方。
Linux拥有对路由的强大支持,在数据平面,你可以很轻松地实现一种路由查找算法,在控制平面,你也可以在用户态实现任何已有的或者你自己设计的路由协议,然而,这一切都是软的,也就是说,都是CPU来完成的。
当我们知道路由和交换的区别之后,就会发现,Linux一直以来都没有实现真正的交换,起码在通用接口层面上没有一个合理的解决方案。Linux的bridge模块?算了吧,它只是实现了一个软网桥,和真正交换机不沾边的。
Linux对硬件交换的支持
记得去年的时候,我曾经拿到过一块交换板,可以直接插在主板的PCI-E上,当时必须使用厂商特定的驱动程序以及配合VLAN技术才能将其用起来。其实很多的交换机可能都采用了Linux作为管理平面和控制平面,然后配置自己的定制硬件和定制驱动来使用。
我曾经想过一种办法用Netfilter技术实现对硬件交换模块的支持,但是,CPU还是要被中断的,整个流程是CPU将数据包拉到bridge或者IP层,然后再交回硬件...正确的方式是根本不用中断CPU,完全通过硬件来转发数据包,只有数据和本地协议栈相关的时候,才中断CPU。而这个思路,意味着你必须重写驱动。
总之,没有一个统一的接口,这就意味着如果你自己想设计一块交换板,没有比较好的标准可循,即便有,可能你也要自己编写或者复制粘贴大量的驱动代码,这将严重影响研发效率。
Linux 4.0的switchdev
一切坏消息在Linux 4.0内核中终结。
Linux 4.0引入了一个switchdev框架,它代表一类拥有“交换”能力芯片的多网口设备的抽象。其中每一个网口就是一个port,在switchdev框架中被注册成一个net_device。除此之外,内核中自带了一个rocker driver,演示了一个实际的设备驱动的实现。整个switchdev的示意图如下所示:
注意,理想化的实现中,OpenFlow控制器可以直接将流表注入到设备中,从而指导设备直接进行数据包交换。流表的内容超级复杂,不是本文的目标,但是相信在后一个内核版本中会出现相关的Document。
采用了硬件交换模块的Linux BOX和原来的截然不同了,它更像是一个高端的专业网络设备,类似Cisco那样的。它看起来就是下面的样子: