1. Open vSwitch简介
Open vSwitch(OVS)作为一款开源的OF软件交换机,基于与平台无关的C代码实现,容易移植到其他环境,既能够作为虚拟机管理平台的软件交换机,也可以作为交换芯片的控制堆栈。
1.1 OVS重要概念
Bridge代表一个以太网交换机(Switch);
交换机包含端口(Ports):Normal、Internal、Patch、Tunnel
一个端口可以有一个或多个接口,允许每个端口连接不止一个的接口
包是通过流转发的
1.2 OVS系统架构
OVS架构分为内核空间、用户空间、配置管理层三部分。
1.2.1 OVS内核空间
内核空间包含了流表和一个或多个datapath模块,datapath模块类似于网桥,主要负责对数据分组进行操作。另外,内核空间中维护的流表规定了针对数据分组应该进行的操作,datapath通过关联流表与其协同完成分组处理过程。
(1)datapath:主要负责实际的数据分组处理,它同时于vswitched和流表保持关联,使OVS上层可以对数据分组处理进行控制。
(2)流表:流表中存储着分组处理的依据----流表项,它指导datapath做出正确的分组处理判断,同时它还与vswitched上下关联,是OVS上层对底层分组处理过程进行管理的接口。
1.2.2 OVS用户空间
用户空间中运行着OVS的守护进程(vswitched)和数据库(ovsdb),它们是OVS的核心功能模块。vswitched类似于OVS的心脏,用来维持OVS的声明周期,而ovsdb就像OVS的大脑,它存储着OVS的配置信息和数据流信息,vswitched和ovsdb协调工作确保OVS健康的运行状态。
(1)vswitched:OVS的守护进程,属于核心模块。负责检索和更新数据库信息,并根据数据库中的配置信息维护和管理OVS。vswitched可以配置一系列特性:基于MAC地址学习的二层交换、支持IEEE 802.1Q VLAN、端口镜像、sFlow监测、连接OF控制器等。vswitched也可以通过Netlink协议与内核模块datapath直接通信。
(2)ovsdb:一个轻量级的OVS数据库,用于管理OVS的配置信息,主要负责保存OVS配置信息和数据流信息等。轻量级数据库服务器ovsdb-server直接管理ovsdb,与ovsdb通信进行数据库的增删改查操作;同时负责向vswitched提供操作ovsdb的能力。vswitched可以通过UNIX Socket机制与ovsdb-server进行通信,用于查询和更新数据库信息,或者在检索数据库信息后做出首个分组的转发策略。
1.2.3 OVS配置管理工具
配置管理层包括ovs-dpctl、ovs-ofctl、ovs-appctl-ovs-vsctl和ovsdb-tool等,主要用于和vswitched、ovsdb之间进行交互操作以及OVS的安装配置和部署。
(1)ovs-dpctl:管理OVS datapath的实用工具,用来匹配交换机内核模块,控制数据分组的转发规则。用户使用该工具可以创建、删除和修改datapath。
(2)ovs-ofctl:OF交换机的命令行管理工具,用于管理OVS作为OF交换机时的各种参数。用户使用该工具可以查询或修改OF交换机的状态、配置和流表项等信息。
(3)ovs-appctl:用于向运行时的OVS守护进程发送命令的工具。
(4)ovs-vsctl:查询和配置OVS数据库的实用工具,用于查询或者变更vswitched的配置信息,该工具会直接更新ovsdb数据库。
2. OVS代码结构
其中,datapath目录是OVS的内核模块,包括VLAN、Tunnel、datapath等C文件以及vport管理,实现普通以太网交换机,具有处理 VLAN、网络访问控制、基于流的控制等功能;ofproto 目录是 OpenFlow 协议相关文件;ovsdb 目录是数据库相关代码;vswitchd目录保存OVS守护进程的源代码;utilities目录包括一些工具代码,如ofctl、vsctl、appctl等;include目录包含常用的头文件;lib目录则保存所有公共模块的实现,如OpenFlow协议解析、JSON数据解析、ovsdb数据解析以及日志模块等。
2.1 守护进程vswitched
OVS守护进程主要负责检索和更新数据库信息,并根据数据库中的配置信息维护和管理OVS,通过守护进程可以配置一系列特性:基于MAC地址学习的二层交换、支持IEEE 802.1Q VLAN、端口镜像、sFlow监测、连接OpenFlow控制器等。守护进程也可以通过Netlink协议与内核模块datapath直接通信。
2.1.1 内部模块组成
守护进程vswitchd进程的模块架构如下图
其中,ovs-vswitchd模块负责和ovsdb-server交互,启动时从配置数据库获取配置信息,并将配置信息下发给ofproto模块。当配置数据库变化时,vswitchd也会实时感知并同步变化。ofproto模块是一个处理OpenFlow协议的库,它负责与控制器交互,并通过调用 dpif 等下层组件和交换机的硬件及软件交互。而ofproto-dpif、dpif是实现ofproto具体功能的下层支撑库,用来和底层的硬件和软件转发模块对接。netdev 是一个网络设备适配层,对网络设备的硬件接口和逻辑接口进行各种操作,如获取接口信息或者设置接口状态等,netdev 对网络设备的具体操作由netdev-provider提供。
由于vswitchd运行于用户态(用户空间),而datapath运行于内核态(内核空间)。当datapath无法匹配到流表条目的报文时,会送给vswitched的ofproto-dpif模块进行模糊匹配转发;如果还是无法匹配到,则由ofproto产生Packet-in事件到控制器,由控制器生成合适的流条目并下发给内核中的流表,然后进行相应的转发操作。
2.1.2 vswitched的核心流程
是用户空间的daemon(守候)进程,其核心是执行ofproto的逻辑,即创建网桥,并处理OF消息和Netlink消息。OVS是遵从OpenFlow交换机规范实现的,以二层分组转发为例,传统交换机(包括 Linux 网桥的实现)通过查找CAM(内容可寻址存储器)表,找到目的MAC地址对应的端口进行数据分组转发;而OVS的实现则是根据入数据分组的SKB(Socket Buffer,存储报文内容的缓存)查找是否有对应的流表项。如果有,说明这个SKB不是流的第一个分组,那么可以在流表项条目的动作表(Action)里找到转发的端口。这里要说明的是, OpenFlow的思想就是所有分组都需要对应一个流表项,基于流表项给出分组的Action,传统的Action无非就是转发、接收或者丢弃,而在SDN中,Action包含更多的定义,如修改SKB的内容、改变数据分组的路径、克隆多份并发到不同路径等。
如果SKB没有对应的流表项,说明这是流表项的第一个分组,需要为这个分组创建一个新的流表项,vswitchd会在一个循环里反复检查有没有ofproto的请求过来,有可能是ovs-ofctl传过来的,也可能是datapath通过Netlink发送的upcall请求,当然大部分情况下,都是flow miss(指内核匹配流表项失败)导致的创建流表项的请求,这时vswitchd会基于OpenFlow规范创建流表项和Action。
(1)vswitchd守护进程启动流程
vswitchd 启动时,首先会从 ovsdb 中获取网桥信息,并将网桥在内核中运行起来。接下来会初始化 ofproto 库,并开始运行 ofproto,接收并处理来自网桥的信息。最后运行ofproto连接管理,接收并处理OF消息。OF消息主要来自控制器和ofctl工具。来自控制器的OF消息,主要是指导流转发的流变更消息,而来自ofctl工具的消息主要是用于测试、监控以及查看等,如添加自定义调试的流表项、查看OVS中的流表信息等。
ofproto.c是实现OpenFlow协议的主文件,里面包含对控制器发送给ofswitch的各种消息处理。handle_openflow()函数是一个协议处理入口函数,其主要功能是将控制器发送的OF 消息分发给具体的处理函数,其中除了会处理标准的OF消息外,还会处理Nicira公司定义的一些扩展消息。
connmgr.c是实现对ofswitch和控制器交互连接的管理,包括如下重要处理:connmgr_send_packet_in()负责向控制器发送Packet-in消息;connmgr_send_flow_removed()负责发送Flow-Removed消息;connmgr_send_port_status()负责发送端口状态变化消息。当ofproto.c处理由控制器发给交换机的消息且需要响应控制器时,可调用connmgr.c中的函数进行回应。
OVS是一个基于二层交换模型的虚拟交换机,数据报文从某个端口接收后,处理流程如图所示
内核中的交换机首先基于SKB生成键值(key),然后基于键值查找流表,并根据匹配结果进行不同的处理。如果能够匹配到合适的流表项,则根据流表项中的Action信息,进行报文的后续处理。如果无法匹配到流条目,则说明交换机不知道如何对报文进行处理,于是将报文信息封装为Netlink消息并发送给用户态的vswitchd进程,由vswitchd来构建合适的流条目下发给内核流表,指导数据流后续报文的转发行为,如转发到某个端口或者丢弃等。
2.1.3 OpenFlow协议的数据结构
OVS源代码中ofproto的文件是与OpenFlow协议相关的主要文件,它定义了针对 OpenFlow 协议的处理方法,其核心数据结构 struct ofproto 代表了一个OpenFlow交换机的模型
struct ofport代表了一个OpenFlow交换机端口,ofport必定属于一个ofproto。交换机端口的数据结构定义如下图。
struct ofproto_class是一个桥接模式(Bridge Pattern)的实现,其结构定义如下图。
在上述数据结构定义中,ofproto 结构表示 OpenFlow 交换机,ofport 结构表示OpenFlow交换机的端口,rule结构表示OpenFlow交换机的流表。ofproto-dpif结构是对 ofproto 结构的一个具体实现,其对应的ofproto_class 结构的实现为ofproto_dpif_class。ofport_dpif结构是ofport的一个具体实现,rule_dpif结构是对规则的一个具体实现。
2.2 OVS数据库(ovsdb)
ovsdb 用于维护交换机的各种配置信息,按特定的结构组织整合在一起并存储在硬盘中,以永久保存。当OVS被重新启动时,ovsdb不会因此而丢失OVS原有配置。OVS守护进程在重启后会从ovsdb读入并恢复OVS的原有配置,从而保证OVS重启后无需重新配置。
此外,网络维护人员还可以通过查询ovsdb进行网络排错。ovsdb将OVS的全部配置信息有条理的组织在一起,这使得排错操作变得非常便捷。网络维护人员既可利用ovs-vsctl提供的一系列命令查询ovsdb中的配置信息来排错,也可以利用ovsdb-tool命令(ovsdb-tool show-log-m)查询数据库的修改日志来排错,从而大大提高了网络维护的效率。
ovsdb中各表之间的关系如图所示。其中每个节点表示一个表;属于“root set”的表用双边框标出;从节点上引出的箭头指向该表所关联的其他表;箭头上标记了属性的名字,属性后跟的符号(?、*、+)表示该表可接多少该属性;“?”表示可接一个或不接,“*”表示可接多个或不接,“+”表示可接一个或多个。
总之,ovsdb 包含 3 级结构,分别是 Table、Record、Column。其中,Table包含 Record,Record 包含 Column,这样的分级结构使数据库中的信息组织形式更加有条理,便于管理和检索。例如,在 ovsdb 中能由守护进程进行操作的最上层的表是Open_vSwitch表(Table),其必须包含一个确切的记录(Record)。只有当这些记录能够由Open_vSwitch表直接或间接可达的时候,在其他表中的记录才有意义。除了少数几个在特殊的“root set”表中的记录,其他不能够由Open_vSwitch表可达的记录会自动从数据库中删除。大部分表都包含两种特殊的属性(Column):other_config 和 external_ids,在任何地方出现的这两种属性都有相同的书写格式和功能。下面进行详细介绍与分析。
2.2.1 表(Table)
Open vSwicth预定义了15个数据表
2.2.2 记录(Record)
在每个数据表中,可以包含多条记录。数据表中的记录,用户可以进行添加、修改和删除操作。例如,在Open_vSwitch表中,每条记录关联一个网桥,在网桥表中,每条记录则表示该网桥的一个端口信息;在流表中,每条记录则代表某个网桥的一条流表项。
2.2.3 属性(Column)
在每个记录中,可以包含多条Column,每个Column表示一条记录的配置项,属性目前仅支持整型(Integer)、实数型(Real)、布尔型(Boolean)以及字符串(String)4种类型。
3. OVS的安装
[email protected]:~$ sudo wget https://www.openvswitch.org/releases/openvswitch-2.11.1.tar.gz
[email protected]:~$ tar zxvf openvswitch-2.11.1.tar.gz
[email protected]:~$ cd openvswitch-2.11.1/
[email protected]:~/openvswitch-2.11.1$sudo ./configure
[email protected]:~/openvswitch-2.11.1$sudo make -j 4 && make install
4. OVS的使用
4.1 交换机创建和端口p0的配置
创建一个新的OVS交换机,并配置一个DPID。
创建一端口p0,设置端口p0的OF端口编号为100,如果在创建时没有指定OF端口号,OVS会自动生成
设置网络设备的接口类型为internal。对于internal类型的网络接口,OVS会同时在Linux上系统中创建一个可以用来收发数据的网络模拟设备。可以为这个网络设备配置IP地址、进行数据监听等等,查看结果。
4.2 虚拟网络空间配置
为了避免网络接口上的地址和本机已有网络地址冲突,我们可以创建一个虚拟网络空间ns0,把p0接口移入网络空间ns0,并配置IP地址192.168.1.100.
4.3 查看OVS交换机
通过ovs-vsctl show命令查看OVS交换机的信息。
4.4 使用ovs-ofctl命令创建并测试OF命令
查看Open vSwtich中的端口信息,从输出结果中,可以获得交换机对应的datapath ID(dpid),以及每个端口的OF端口编号,端口名称,当前状态。
4.4.1 查看交换机中所有Table
4.4.2 查看交换机中所有流表项
4.4.3 查看交换机中所有端口信息
4.4.4 两个端口相互测试