OVS源码结构分析

1. OVS内部结构分析

下图是OVS(Open vSwitch)系统层面的逻辑图。

其中datapath是处于系统的核心层(kernel space),我们可以将datapath理解为一个网桥(linux bridge)。处于用户态(user space)的主要是openvswitch client、openflow client、ofproto library、netdev等等。

OVS源码结构分析_第1张图片

如上图中,ofproto即openflow protocol的缩写,它是一个openflow的库,OVS的客户端(如ovs-vswitchd、ovs-openflowd)就是通过调用这个库来操作OVS的控制中心。

netdev则是设备抽象的API,它是由linux内核提供的,通过netdev这个API,可以直接与内核层的网络设备通信。

OVS源码结构分析_第2张图片

同时Flow table也处在内核层中,这样当datapath依照flow table的规则处理数据流时就可以直接将操作传送给内核层的网络设备进行操作,这样的传输性能是十分强悍的。

2. Openvswitch的代码结构

Openvwitch进行数据流交换的主要逻辑都是在ovs-vswitchd和openvswitch.ko里面实现的。

这里写图片描述

ovs-vswitchd会从ovsdb-server读取配置,然后调用ofproto层进行虚拟网卡的创建或者流表的操作。
ofproto是一个库,实现了软件的交换机和对流表的操作。
netdev层抽象了连接到虚拟交换机上的网络设备。
dpif层实现了对于流表的操作。

对于OVS来讲,有以下几种网卡类型

1). netdev: 通用网卡设备 eth0 veth
接收: 一个netdev在L2收到报文后回直接通过ovs接收函数处理,不会再走传统内核协议栈.
发送: ovs中的一条流指定从该netdev发出的时候就通过该网卡设备发送

2). internal: 一种虚拟网卡设备
接收: 当从系统发出的报文路由查找通过该设备发送的时候,就进入ovs接收处理函数
发送: ovs中的一条流制定从该internal设备发出的时候,该报文被重新注入内核协议栈

3). gre device: gre设备. 不管用户态创建多少个gre tunnel, 在内核态有且只有一个gre设备
接收: 当系统收到gre报文后,传递给L4层解析gre header, 然后传递给ovs接收处理函数
发送: ovs中的一条流制定从该gre设备发送, 报文会根据流表规则加上gre头以及外层包裹ip,查找路由发送

3.创建ovs bridge流程分析:

OVS源码结构分析_第3张图片

1.通过ovs-vsctl 创建网桥,将创建参数发送给ovsdb-server,ovsdb-server将数据写入数据库。

2.ovs-vswitchd从ovsdb-server中读取创建网桥的信息,在ovs-vswithd层创建一个bridge结构体信息

3.然后将brdige信息应用到ofproto层,在ofproto层通过ofproto_create创建网桥,ofproto_create通过用户指定的网桥类型查找包含该类型的ofproto provider(目前只支持一个ofproto provider)。
查找后创建ofproto结构体(该结构体也表示一个bridge),并通过ofproto provider 构造函数创建ofproto provider的私有信息。

4.ofproto-dpif 层,构造函数完成如下:ofproto-dpif会为相同类型的ofproto创建一个backer结构体,所有类型的ofproto的backer使用全局列表表示。ofproto-dpif通过backer关联dpif。同时backer关联upcall处理线程
netdev没有实现upcall注册函数,所以对应的backer线程实际上不做任何处理,但依然会有该处理线程。netlink 通过backer启动的线程实现处理upcall数据包的处理。

vswitchd是ovs中最核心的组件,openflow的相关逻辑都在vswitchd里实现,一般来说ovs分为datapath, vswitchd以及ovsdb三个部分,datapath一般是和具体是数据面平台相关的,比如白盒交换机,或者linux内核等。ovsdb用于存储vswitch本身的配置信息,比如端口,拓扑,规则等。vswitchd本身是分层的结构,最上层daemon主要用于和ovsdb通信,做配置的下发和更新等,中间层ofproto,用于和openflow控制器通信,以及通过ofproto_class暴露了ofproto provider接口,不同平台上openflow的具体实现就通过ofproto_class统一。

Open vSwitch实现了两种dpif。lib/dpif-netlink.c 特定Linux实现的dpif,该dpif与Open vSwith实现的内核模块通信。内核模块执行所有的交换工作,将内核态不匹配的数据包发送到用户态。dpif封装调用内核接口。lib/dpif-netdev.c 是一种通用的 dpif 实现。该dpif就是Open vSwith在用户态的实现。数据包的交换不会进入内核。struct dpif_class是datapath interface实现的工厂接口类,用于和实际的datapath, e.g. openvswitch.ko, 或者userspace datapath交互。目前已有的两个dpif的实现是dpif-netlink和dpif-netdev,前者是基于内核datapath的dpif实现,后者基于用户态datapath。代码可以在lib/dpif-netlink.c以及lib/dpif-netdev.c里找到。

你可能感兴趣的:(openvswitch)