OVS框架以及源码笔记1

引言

是基于2.3.90的版本

1.OVS网络架构

OVS全名字Openvswitch,是一个虚拟交换机,支持Open Flow协议,被远端的controller通过Open Flow协议统一管理着,从而实现对接入的虚拟机(或设备)镜像组网和互通,整体组网结构如下:
OVS框架以及源码笔记1_第1张图片

2.OVS内部架构

OVS框架以及源码笔记1_第2张图片

  1. ovs-vswitchd 是主要模块,实现vswitch的守护进程daemon
  2. ovsdb-server 是轻量级数据库服务器,用于ovs的配置信息
  3. ovs-vsctl通过和ovsdb-server通信,查询和更新vswitch的配置
  4. ovs-dpctl 用来配置vswitch内核模块的一个工具
  5. ovs-appctl发送命令消息到ovs进程
  6. ovs-ofctl 查询和控制OpenFlow虚拟交换机的流表
  7. datapath内核模块,根据流表匹配结果做相应处理

3.OVS代码架构

OVS框架以及源码笔记1_第3张图片

  1. vswitchd是ovs主要的用户态程序,他从ovsdb-server读取配置并发送到ofproto层,也从ofproto读取特定的状态和统计信息并发送到数据库。
  2. ofproto是openflow的接口层,负责和Openflow controller通信并通过ofproto_class与ofprotot provider底层交互
  3. ofproto-dpif是ofproto接口类的具体实现
  4. netdev是ovs系统的网络设备抽象(比如Linux的net_device或交换机的port),netdev_class定义了netdev-provider的具体实现需要的接口,具体的平台实现需要这些统一的接口,从而完成netdev设备的创建、销毁、打开、关闭等一系列操作
3.1datapath

由于openvswitch用户态代码相对复杂,首先从内核模块入手分析。
datapath为ovs内核模块,负责执行数据处理,也就是把从接收端口收到的数据包在流表中进行匹配,并执行匹配到的动作。一个datapath可以对应多个vport,一个vport类似物理交换机的端口概念。一个datapath关联一个flow table,一个flow table包含多个条目,每个条目包括两个内容:一个match/key和一个action

3.1.1数据流向

OVS框架以及源码笔记1_第4张图片
一般的数据包在linux网络协议中的流向为上图中的蓝色箭头流向:网卡eth0收到数据包后判断报文走向,如果是本地报文把数据传送到用户态,如果是转发报文根据选路(二层交换或三层路由)把报文送到另一个网卡如eth1.当有OVS时,数据流向如红色所示:从网卡eth0收到报文后进入ovs的端口,根据key值进行流表匹配,如果匹配成功执行流表对应的action;如果失败通过upcall送入用户态处理。

3.1.2模块初始化

内核模块采用 module_init(dp_init)进行 datapath 的初始化,代码如下:

OVS框架以及源码笔记1_第5张图片
其中 dp 的 genl_family 注册了如下四个类型:

OVS框架以及源码笔记1_第6张图片

3.1.3收包处理

通过 vport 注册的回调函数 netdev_frame_hook()->netdev_frame_hook()->
netdev_port_receive()->ovs_vport_receive()处理接收报文,ovs_flow_key_extract()
函数生成 flow 的 key 内容用以接下来进行流表匹配,最后调用 ovs_dp_process_packet()
函数进入真正的 ovs 数据包处理,代码流程如下:
OVS框架以及源码笔记1_第7张图片

3.1.4流表哈希桶

流表采用 hash 的方式排列存放,流表的 hash 头结点存储数据结构如下:
OVS框架以及源码笔记1_第8张图片
该 hash 桶的初始化函数 alloc_buckets (),生成的数据格式可参考如下:
OVS框架以及源码笔记1_第9张图片

3.1.5流表创建

用户态通过netlink进行datapath流表更新的入口函数都定义在dp_flow_genl_ops中,流表创建的入口函数是ovs_flow_cmd_new函数,、
代码分析如下:
OVS框架以及源码笔记1_第10张图片
根据上述流程给出流表的主要数据结构如下:
OVS框架以及源码笔记1_第11张图片

3.1.6流表查询

流表查找主要是查表关键字的匹配,关键字数据结构如下,根据 skb 中的 Ethernet 帧
生成 key 的函数为 ovs_flow_key_extract():

OVS框架以及源码笔记1_第12张图片
流表查询的入口函数 ovs_flow_tbl_lookup_stats(),flow 的匹配策略是和流表中所有
mask 和所有 key 进行匹配处理,为了加速查询效率,在调用真正的流表查询函数
flow_lookup()之前,对于 mask 的查询采用了缓存机制,实现原理是首先查询缓存的
mask_cache_entry,这些 cache 是查询成功后形成的 cache,并针对 cache 采用分段查询
的方式,代码如下:
OVS框架以及源码笔记1_第13张图片
OVS框架以及源码笔记1_第14张图片

3.1.7action处理

ovs 的 action 类型如下,使用 nla_type()函数获取 nl_type 的值,入口处理函数为
do_execute_actions()。
OVS框架以及源码笔记1_第15张图片
 OVS_ACTION_ATTR_OUTPUT:获取 port 号,调用 do_output()发送报文到该 port;
 OVS_ACTION_ATTR_USERSPACE:调用 output_userspace()发送到用户态;
 OVS_ACTION_ATTR_HASH:调用 execute_hash()获取 skb 的 hash 赋值到 ovs_flow_hash
 OVS_ACTION_ATTR_PUSH_VLAN:调用 push_vlan()增加 vlan 头部
OVS框架以及源码笔记1_第16张图片
OVS_ACTION_ATTR_RECIRC:在 action_fifos 全局数组中添加一个 deferred_action;
13 / 30
OVS_ACTION_ATTR_SET:调用 execute_set_action()设置相关参数; OVS_ACTION_ATTR_SAMPLE:概率性的发送报文到用户态(详见 sflow 章节)。

3.1.8 upcall处理

当没有找到匹配的流表时,内核通过 netlink 发送报文到用户层处理,入口函数
ovs_dp_upcall(),该函数调用 queue_userspace_packet()构造发往用户层的 skb,通过
netlink 通信机制发送到用户层,其中形成的主要数据格式如下:
OVS框架以及源码笔记1_第17张图片

3.2 ovs-vswitchd

vswitchd 作为守护进程和 ovsdb 通信以及和 controller 进行 openflow 通信,并完成
和底层内核的交互。代码在 vswitchd/目录下面,可以从 main 函数入口分析,整体处理流
程如下:
OVS框架以及源码笔记1_第18张图片

3.3 ofproto

ofproto 层通过 ofproto_class 类(实现是 ofproto_dpif_class)实现了 openflow 的
接口,它主要包括如下几个接口类对象:
 ofproto 代表了一个 openflow switch 的具体实现,是 ofproto 层的整体结构体;
 ofport 代表了一个 openflow switch 的端口,关联一个 netdev 设备;
 ofrule 代表了一条 openflow 规则,rule 里面包含一组 actions;
 ofgroup 代表了一个 openflow 的行为组合,openflow 1.1+以上版本支持;

3.3.1 ofproto数据结构

OVS框架以及源码笔记1_第19张图片

3.3.2 ofproto创建流程

其中 rule 和 group 的创建流程不在本节列出

OVS框架以及源码笔记1_第20张图片

3.3.3 udpif

udpif 接口层采用多个线程处理内核发往用户层的 upcall 请求,入口函数为
udpif_set_threads(),主要处理流程如下
OVS框架以及源码笔记1_第21张图片

3.4 openflow

OpenFlow 是用于管理交换机流表的协议,ovs-ofctl 则是 OVS 提供的命令行工具。
在没有配置 OpenFlow controller 的模式下,用户可以使用 ovs-ofctl 命令通过
OpenFlow 协议去连接 OVS,创建、修改或删除 OVS 中的流表项,并对 OVS 的运行状况进
行动态监控。

3.4.1 openflow 连接建立

在 bridge_reconfigure()函数中调用 bridge_configure_remotes 进行 openflow 连接
的相关处理,主要创建两个对象:ofconn 作为客户端负责和远端 conntroller 主动建立连
接;ofservice 作为服务器提供被动式的监听服务,主要数据结构及流程如下图:
OVS框架以及源码笔记1_第22张图片

3.4.2 ofconn 报文处理

入口函数 ofproto_run(),主要调用流程如下:
OVS框架以及源码笔记1_第23张图片

3.4.3 ofservice 报文处理

OVS框架以及源码笔记1_第24张图片

3.4.4 flow_mod 消息格式

openflow 协议消息处理入口函数是 handle_openflow(),其中最重要的是 flow_mod 流
表项的处理,flow_mod 流表的报文格式主要有四部分组成:openflow 头部、flow_mod 固
定字段、match 字段和 instruction 字段。
match 分为 OFPMT_STANDARD 和 OFPMT_OXM 两种类型,可以包含多个 oxm,instruction
可以包含多个 action,也可以没有。抓包示例可参考如下:
OVS框架以及源码笔记1_第25张图片

3.4.5 match 字段处理

match 字段的解析处理入口函数为 ofputil_pull_ofp11_match(),其中的核心处理函数
为 nx_pull_raw(),主要流程是解析出 flow_mod 的 match 字段,和 flow 中的 match 相关参
数做一些合法性检测,最后使用解析出的 value 更新 flow 中的 match。
目前 match 匹配域用的较多的是 OXM 即 TLV 格式,字段解析结构示意图如下:
OVS框架以及源码笔记1_第26张图片
原文链接:

3.5sflow

采样流 sFlow(Sampled Flow)是一种基于报文采样的网络流量监控技术,主要用于
对网络流量进行统计分析。sFlow 系统包含一个嵌入在设备中的 sFlow Agent 和远端的
sFlow Collector。其中,sFlow Agent 通过 sFlow 采样获取本设备上的接口统计信息和数
据信息,将信息封装成 sFlow 报文,当 sFlow 报文缓冲区满或是在 sFlow 报文缓存时间超
时后,sFlow Agent 会将 sFlow 报文发送到指定的 sFlow Collector。sFlow Collector 对
sFlow 报文进行分析,并显示分析结果,组网图如下:
OVS框架以及源码笔记1_第27张图片

3.6 ovs-vsctl

ovs-vsctl 根据用户的命令和 ovsdb-server 通信,用于查询和更新数据库配置。而
vswithcd 会在需要重新更新配置的时候和 ovsdb 交互,然后和内核 dp 模块通过 netlink
消息执行真正的操作。本节以添加网桥、端口、vxlan 端口为例分析主要实现流程,其中
ovsctl 进程的主要处理流程如下:
OVS框架以及源码笔记1_第28张图片
OVS框架以及源码笔记1_第29张图片

你可能感兴趣的:(OVS,OVS)