1.openvswitch与openflow 协议
1.1openflow协议
SDN,即Software Defined Networking:软件定义网络。其本质就是使控制平面与转发平面分离开,使控制平面能运行在独立于网络设备的高性能计算机上.
SDN是一种思想,并非一种具体的技术。而OpenFlow协议,便是一种实现这种思想的具体实现,是连接控制平面和转发平面之间通信的桥梁。
openflow协议的基本内容:
一、两个实体是Switch跟Controller。Controller在网络中相当于上帝,可以知道网络中所有的消息,可以给交换机下发指令。Switch就是一个实现Controller指令的实体,根据流表转发。
二、table,flow,match,action:openflow交换机可以有多个table,每个table包含多条flow,flow由match+action组成,match为匹配字段,数据包L2到L4的信息;action为匹配match后所要执行的操作,如指定端口出去,对报文进行编辑等。
例子:ovs-ofctl add-flow br0 “in_port=1,nw_src=192.168.1.1,actions=mod_nw_src:192.181.137.1,output:2”
三、openflow消息:分为三大类,controller-to-switch,Asynchronous,Sysmetic
Controller-to-Switch
控制器所发起的消息:
1) Feature:查询交换机能力;
2) Configuration:设置或者查询配置参数;
3) Modify-State:增删改流表或者组表条目,设置交换机端口属性
4) Packet-Out: 这个消息用于控制器指定从交换机的特定端口发送数据包,或者用于转发通过Packet-in消息接收到的数据包。Packet-out消息中包含一个完整的数据包或者指针,以及action.
5) Barrier:用于控制器保证消息的依赖关系
Asynchronous
交换机发起的消息
1) Packet-In:对于出现flowentry mismatch的数据包,交换机向控制器发送packet-in事件。数据包本身要么被完全包含在packet-in消息中,要么被buffer在交换机中,反正都是等着控制器的Packet-out事件来处理就对了。
2) Flow-Removed: 交换机通知控制器已经没有了某个流表条目
3) Port-Status:当端口配置或者状态变化时通知控制器
Sysmetic
两方都可以发起的消息,不用协商,分为以下三类:
1) Hello:交换机和控制器建立起连接后的维护消息
2) Echo:echo request和echo reply配对
openflow协议报文格式
struct ofp_header {
uint8_t version;
uint8_t type;
ovs_be16 length;
ovs_be32 xid; /* Transaction id associated with this packet. Replies use the same id as was in the request to facilitate pairing. */
};
openvswitch-2.3.2/lib/ofp-util.h定义了所有所有消息的内容结构
1.2openvswitch简介
openvswitch(ovs)是openflow协议的具体实现,可以实现基于linux内核的软件交换机,是一个开源软件。一个虚拟交换机可以有几十个端口来连接虚拟机虚拟网卡,虚拟机发出的数据包通过ovs交换机利用流表进行转发,通过连接物理网卡将数据往外发。
ovs-vswitchd 主要模块,实现switch的daemon,包括一个支持流交换的Linux内核模块;
ovsdb-server 轻量级数据库服务器,提供ovs-vswitchd获取配置信息;
ovs-vsctl 查询和更新ovs-vswitchd的配置,对ovsdb进行操作;
ovs-appctl:主要是向OVS守护进程发送命令的;
ovs-ofctl 查询和控制OpenFlow交换机和控制器;
ovs-dpctl:一个工具,用来配置交换机内核模块,可以控制转发规则。
openvswitch.ko为Linux内核模块,支持数据流在内核的交换
1.3ovs源码安装
1.下载解压
2../configure --with-linux=/lib/modules/$(uname -r)/build 编译ovs linux内核模块
3.make&make install
4.make modules_install 所做的动作 1.将编译好的模块放入/lib/module/`uname -r`下 2.用depmod更新modules.dep文件
5.modprobe openvswitch/gre/vxlan 加载ovs内核模块 lsmod | grep openvswitch查看
6.配置ovsdb ovsdb-tool create /usr/local/etc/openvswitch/conf.db vswitchd/vswitch.ovsschema(默认db模板)
7.启动ovsdb
ovsdb-server /root/software/openvswitch2.8.1/etc/openvswitch/conf.db --remote=punix:/root/software/openvswitch2.8.1/var/run/openvswitch/db.sock \ --remote=db:Open_vSwitch,Open_vSwitch,manager_options --pidfile=/var/run/ovsdb.pid --detach \
8.启动ovs-vswitch进程
ovs-vswitchd unix:/root/software/openvswitch2.8.1/var/run/openvswitch/db.sock --pidfile=/var/run/ovs.pid --detach --log-file=/var/log/ovs.log
2 ovs源码分析
ovs代码结构:
从图中可以看出 OVS 的分层结构,最上层 vswitchd 主要与 ovsdb 通信,做配置下发和更新等,中间层是 ofproto ,用于和 OpenFlow 控制器通信,并基于下层的 ofproto provider 提供的接口,完成具体的设备操作和流表操作等工作。
dpif 层实现对流表的操作。
netdev 层实现了对网络设备(如 Ethernet)的抽象
一个connmgr对应多个ofconn(如一个网桥连接多个控制器,则需要建立相应多个ofconn实例;和ofctl等工具连接时也要建立ofconn实例);一个ofconn对应一个rconn;一个rconn对应多个vconn(因为和控制器建立连接外,可能还会实现snoop功能,即监测并复制交互的of消息,则一个rconn会对应一个vconn和一个vconn结构体类型的数组monitor。
由于openvswitch用户态代码相对复杂,首先从内核模块入手分析。
datapath为 ovs内核模块,负责执行数据处理,也就是把从接收端口收到的数据包在流表中进行匹配,并执行匹配到的动作。一个datapath可以对应多个vport,一个vport类似物理交换机的端口概念。一个datapth关联一个flow table,一个flow table包含多个条目,每个条目包括两个内容:一个match/key和一个action。
一般的数据包在linux网络协议栈中的流向为蓝色箭头流向:从网卡上接受到数据包后层层往上分析,最后离开内核态,把数据传送到用户态。当然也有些数据包只是在内核网络协议栈中操作,然后再从某个网卡发出去。当有 OVS时,数据流向如红色所示:从网卡 eth0收到报文后进入ovs的端口,根据 key值进行流表匹配,如果匹配成功执行流表对应的 action;如果失败通过upcall送入用户态处理。
通过vport注册的回调函数netdev_frame_hook()->netdev_frame_hook()-> netdev_port_receive()->ovs_vport_receive()处理接收报文,ovs_flow_key_extract()函数生成flow的key内容用以接下来进行流表匹配,最后调用ovs_dp_process_packet()函数进入真正的ovs数据包处理