Open vSwitch源码阅读笔记(下)

作者简介:刘成天,就职于赛特斯信息科技股份有限公司,高级工程师,目前工作地点南京,主要从事vCPE和路由器相关的研发工作

引言

本文主要对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函数,主要处理流程如下:


  • 本站原创文章仅代表作者观点,不代表SDNLAB立场。所有原创内容版权均属SDNLAB,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用,转载须注明来自 SDNLAB并附上本文链接。 本站中所有编译类文章仅用于学习和交流目的,编译工作遵照 CC 协议,如果有侵犯到您权益的地方,请及时联系我们。
  • 本文链接https://www.sdnlab.com/18674.html
分享到:
相关文章
条评论

登录后才可以评论

certusnet-sky 发表于17-03-06
0