我试图了解 Open vSwitch 如何利用 linux 基础架构的内部机制,特别是 OVS 网桥和 br-xx(linux 网桥)之间的区别。我是这个领域的新手,所以我可能在很多方面都错了。
背景:到目前为止,我知道要创建虚拟网络,可以使用网络命名空间来模拟主机(网络的端点),并且可以使用 veth 对作为连接两个节点的链接。此外,使用 iproute2 包,可以设置网桥(br-xx)并向其添加虚拟接口,从而完成虚拟网络。
为了了解 OVS 网桥和 linux 网桥(由 iproute2 创建)之间的区别,我浏览了 mininet 代码。我可以弄清楚的一件事是 mininet 依赖 ovs-vsctl 来创建 OVS 网桥。我探索了 OVS 代码以弄清楚它们实际上是如何设置的,以及它们与 linux 网桥有何不同,但没有取得多大成功。
问题:OVS 网桥(使用 ovs-vsctl 创建)和 linux 网桥(使用 iproute2 创建)在内部有何不同?我直观地感觉它们都基于两个不同的内核模块在后面(在Open vSwitch的上下文中它称为datapath,不确定linux桥的内核模块的名称)。我的直觉对吗?如果是,我如何创建自己的内核模块并使用它作为“后端”建立一个桥接器?
在这里分享一些理解,这可能不像你想的那么低层次,因为我没有在这个层次/方面投入太多精力。
首先,Linux 桥接器依赖内核堆栈进行简单的 L2 转发。换句话说:根据映射规则转发数据包
src_mac
,in_port
存储在系统ARP缓存中。列出转发规则(映射)
iproute2
:使用老式(但打印精美)
arp
命令:此外,所有常规网络工具都可以在 Linux 网桥上的设备(veth pair、tun/tap)上运行良好。
相比之下,OVS 维护自己的转发表和转发规则,分别称为
flow table
和flow
。一旦数据包进入 OVS 网桥,它将与流(规则)匹配,然后执行规则中指定的操作。这种转发机制更加灵活、可扩展,最重要的是——可编程。以下面流表中的第二条规则为例:
in_port=1
匹配标准:来自端口 1 ( ) 和 vlan 标签 18 (dl_vlan=18
)的入口数据包(到此 OVS 网桥)mod_vlan_vid=43
进行正常的L2转发()NORMAL
br-int
相应
src_mac:in_port
的映射也存储在它自己的fdb
(转发数据库)中:具体来说,如果流表中没有指定其他规则,OVS 网桥将遵循默认规则 (
action=NORMAL
),该规则执行正常的 L2 转发,就像普通的 Linux 网桥一样。其次,随着 OVS 从内核堆栈中提升数据包,因此依赖于内核堆栈的网络工具可能会停止在 OVS 设备(端口)上工作,例如无法
tcpdump
捕获 OVS 上的任何数据包patch port
,并且iptables
规则将无法在 OVS 端口上工作任何一个。第三,关于实现:Linux桥接器非常直接,可能是内核堆栈中最早的网络设备之一,并且只有数百行代码,请查看Kernel 5.1中的代码。相反,OVS 代码要复杂得多,因为它要处理很多事情,才能像可编程、强大、高效和全功能的 OpenFlow 交换机一样工作。如果您想快速了解一下,请查看早期版本(功能较少)。