引言
本文主要对OpenvSwitch(基于2.3.90版本)重点模块的源码实现流程做了简要的阅读记录,Open vSwitch源码阅读笔记(上)已提供,此篇是对上篇的追述及补充,适合阅读OpenvSwitch源码的初级读者参考使用。在阅读源码时参照了网上很多博客尤其SDNLAB的网站文章,再次统一致谢,并将知识分享传递下去。
3.5 sflow
采样流sFlow(Sampled Flow)是一种基于报文采样的网络流量监控技术,主要用于对网络流量进行统计分析。sFlow系统包含一个嵌入在设备中的sFlow Agent和远端的sFlow Collector。其中,sFlow Agent通过sFlow采样获取本设备上的接口统计信息和数据信息,将信息封装成sFlow报文,当sFlow报文缓冲区满或是在sFlow报文缓存时间超时后,sFlow Agent会将sFlow报文发送到指定的sFlow Collector。sFlow Collector对sFlow报文进行分析,并显示分析结果,组网图如下:
3.5.1 sflow初始化
SFlow的配置入口函数是bridge_configure_sflow(),该函数创建SFlow相关的数据区并初始化相应配置,形成的主要数据结构如下:
3.5.2 sflow流表生成
sflow的实现是在用户态生成sflow的流表并配置到内核datapath,内核完成数据采样,发送到用户态,然后有上层sflow agent发送到collector。sflow在用户态生成sflow的流表。流表生成的代码调用流程add_sflow_action()->compose_sflow_cookie ()->compose_sample_action(),生成OVS_ACTION_ATTR_SAMPLE类型的action,主要代码如下:
3.5.3 sflow内核处理
sflow在内核执行action的时候处理,入口函数do_execute_actions()->sample(),代码如下,如果是最后一个action,调用output_userspace()发送数据到用户空间;否则把该action加入到队列中等待执行,代码如下:
3.5.4 sflow消息处理
内核datapath采样的数据通过netlink发送到用户空间的vswithd进程,接收函数为recv_upcalls(),调用process_upcall()函数进入核心处理流程,其中对SFLOW_UPCALL分支的处理就是sflow的入口,处理函数dpif_sflow_received(),核心流程如下:
3.6 ovs-vsctl
ovs-vsctl根据用户的命令和ovsdb-server通信,用于查询和更新数据库配置。而vswithcd会在需要重新更新配置的时候和ovsdb交互,然后和内核dp模块通过netlink消息执行真正的操作。本节以添加网桥、端口、vxlan端口为例分析主要实现流程,其中ovsctl进程的主要处理流程如下:
3.6.1 添加网桥
用户态shell键入命令ovs-vsctl add-br br0,启动vsctl进程用户完成数据库配置,流程如上面所述,最后调用add-br对应的run函数cmd_add_br(),流程如下:
vswithcd检测到数据库的设置后完成业务配置,流程如下:
内核datapath通过OVS_DATAPATH_FAMILY通道收到一个 OVS_DP_CMD_NEW类型的添加网桥的命令,该命令绑定的回调函数为ovs_dp_cmd_new(),处理流程如下:
3.6.2 添加端口
shell键入命令ovs-vsctl add-port br0 eth0(这里分析netdev类型的vport端口,vxlan在下一章节单独分析),vsctl调用add-port对应的函数cmd_add_port()配置数据库,流程如下:
vswitchd调用dpif_netlink_port_add()通过netlink发送对应消息到内核,流程和上一节所述的添加网桥类似,如下所示:
内核datapath通过OVS_VPORT_FAMILY通道收到一个类型为OVS_VPORT_CMD_NEW的添加端口的命令,该命令绑定的回调函数为ovs_vport_cmd_new (),处理流程如下:
3.7 vxlan
vxlan端口是ovs的OVS_VPORT_TYPE_VXLAN类型的隧道端口,用户态netdev库通过netdev_vport_tunnel_register()注册vport_class结构,它包含如vxlan、gre等各种类型隧道的相关处理函数。
3.7.1添加vxlan端口
添加命令为ovs-vsctl add-port br0 vxlan -- set interface vxlan type=vxlan,用户态处理流程和上节的添加端口相同,不同时的是对vxlan端口的参数配置,发往内核dp的消息类型为OVS_VPORT_TYPE_VXLAN,流程如下:
3.7.2 内核vxlan创建
内核ovs_vport_cmd_new ()函数中ovs_vport_add()调用ovs_vxlan_vport_ops对应的操作函数,其中创建函数vxlan_tnl_create()流程如下:
3.7.3 vport数据结构
根据上述流程分析,vxlan类型的vport数据结构如下:
3.7.4 vxlan报文格式
3.7.5 vxlan收包处理
vxlan隧道报文的处理的入口函数是udp sock监听函数vxlan_udp_encap_recv(),处理流程如下:
3.7.6 vxlan发包处理
vlan在执行action时,判断需要发送数据的时候调用发送函数,函数调用do_execute_actions()->do_output()->ovs_vport_send()->vxlan_tnl_send(),这里vxlan_tnl_send()函数即为创建vport端口是注册ovs_vxlan_vport_ops的send函数,主要处理流程如下: