您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 人事档案/员工关系 > openvswitch源代码分析
Openvswitch(OVS)源代码分析系列转载请注明原文出处,原文地址为:(OVS)源代码分析之简介云计算是现在IT行业比较流行的,但真正什么是云计算业界也没有个什么统一的定义(很多公司都是根据自己的利益狭隘的定义云计算),更别说什么标准规范了。所以现在就有很多人说云计算只不过是个幌子,是个嘘头,没点实用的,嘴上说说而已,虽然我也不太清楚什么叫做云计算,云计算的定义究竟是什么,但我根据我公司现在做的云计算产品来说,对于云计算服务还是懂些的。我觉得那并不是什么幌子、嘘头,但如果说这云计算技术还不太成熟,我倒还勉强认可的。若把云计算比作一个人的话,我个人觉得现在它正是二十岁的样子,到三十多岁就算是比较成熟了,所以大概就能想象的到云计算现在的境况了。下面就来简介下实现云计算的一些技术,我对云计算并没有什么研究,也没能达到从全局的角度来分析云计算技术,更别说从一些更高的位置来分析问题,我所能介绍的仅仅是我一个小程序员在工作中所遇到的一些和云计算有关的技术,日积月累,希望终有一天能成为云计算“砖家”。云计算是个全世界的话题,所以也有全世界的能人异士来为实现这个云计算而奋斗。我现阶段遇到的有关云计算的技术就是openVswitch、openStack技术和Docker技术。那就先从openVswitch开始介绍起,我会用一系列blog来分析openVswitch的相关数据结构和工作流程,以及各个重要模块的分析。所有的介绍都是基于源码的分析,希望对初学着有点用。openVswitch,根据其名就可以知道这是一个开放的虚拟交换机(openvirtualswitch);它是实现网络虚拟化SDN的基础,它是在开源的Apache2.0许可下的产品级质量的多层虚拟交换标准。设计这个openVswitch的目的是为了解决物理交换机存在的一些局限性:openVswitch较物理交换机而言有着更低的成本和更高的工作效率;一个虚拟交换机可以有几十个端口来连接虚拟机,而openVswitch本身占用的资源也非常小;可以根据自己的选择灵活的配置,可以对数据包进行接收分析处理;同时还支持标准的管理接口和协议,如NetFlow,sFlow,SPAN,RSPAN等。OpenvSwtich模块介绍当前最新代码包主要包括以下模块和特性:ovs-vswitchd主要模块,实现switch的daemon,包括一个支持流交换的Linux内核模块;ovsdb-server轻量级数据库服务器,提供ovs-vswitchd获取配置信息;ovs-brcompatd让ovs-vswitch替换Linuxbridge,包括获取bridgeioctls的Linux内核模块;ovs-dpctl用来配置switch内核模块;一些Scriptsandspecs辅助OVS安装在CitrixXenServer上,作为默认switch;ovs-vsctl查询和更新ovs-vswitchd的配置;ovs-appctl发送命令消息,运行相关daemon;ovsdbmonitorGUI工具,可以远程获取OVS数据库和OpenFlow的流表。ovs-openflowd:一个简单的OpenFlow交换机;ovs-controller:一个简单的OpenFlow控制器;ovs-ofctl查询和控制OpenFlow交换机和控制器;ovs-pki:OpenFlow交换机创建和管理公钥框架;ovs-tcpundump:tcpdump的补丁,解析OpenFlow的消息;上面是网上提到的一些openVswitch的主要模块。其实openVswitch中最主要的还是datapath目录下的一些文件。有端口模块vport等,还有关键的逻辑处理模块datapath等,以及flow等流表模块,最后的还有action动作响应模块,通道模块等等。下面来介绍下其工作流程:一般的数据包在linux网络协议栈中的流向为黑色箭头流向:从网卡上接受到数据包后层层往上分析,最后离开内核态,把数据传送到用户态。当然也有些数据包只是在内核网络协议栈中操作,然后再从某个网卡发出去。但当其中有openVswitch时,数据包的流向就不一样了。首先是创建一个网桥:ovs-vsctladd-brbr0;然后是绑定某个网卡:绑定网卡:ovs-vsctladd-portbr0eth0;这里默认为绑定了eth0网卡。数据包的流向是从网卡eth0上然后到openVswitch的端口vport上进入openVswitch中,然后根据key值进行流表的匹配。如果匹配成功,则根据流表中对应的action找到其对应的操作方法,完成相应的动作(这个动作有可能是把一个请求变成应答,也有可能是直接丢弃,也可以自己设计自己的action);如果匹配不成功,则执行默认的动作,有可能是放回内核网络协议栈中去处理(在创建网桥时就会相应的创建一个端口连接内核协议栈的)。其大概工作流程就是这样了,在工作中一般在这几个地方来修改内核代码以达到自己的目的:第一个是在datapath.c中的ovs_dp_process_received_packet(structvport*p,structsk_buff*skb)函数内添加相应的代码来达到自己的目的,因为对于每个数据包来说这个函数都是必经之地;第二个就是自己去设计自己的流表了;第三个和第二个是相关联的,就是根据流表来设计自己的action,完成自己想要的功能。openVswitch(OVS)源代码分析之数据结构记得Pascal之父、结构化程序设计的先驱NiklausWirth最著名的一本书,书名叫作《算法+数据结构=程序》。还有位传奇的软件工程师FrederickP.Brooks曾经说过:“给我看你的数据”。因此可见数据结构对于一个程序来说是多么的重要,如果你不了解程序中的数据结构,你根本就无法去理解整个程序的工作流程。所以在分析openVswitch(OVS)源代码之前先来了解下openVswitch中一些重要的数据结构,这将对你分析后面的源代码起着至关重要的作用。按照数据包的流向来分析下涉及到一些重要的数据结构。第一、vport端口模块中涉及到的一些数据结构:[cpp]viewplaincopy1.//这是表示网桥中各个端口结构体2.structvport{3.structrcu_headrcu;//一种锁机制4.structdatapath*dp;//网桥结构体指针,表示该端口是属于哪个网桥的5.u32upcall_portid;//Netlink端口收到的数据包时使用的端口id6.u16port_no;//端口号,唯一标识该端口7.8.//因为一个网桥上有多个端口,而这些端口都是用哈希链表来存储的,9.//所以这是链表元素(里面没有数据,只有next和prev前驱后继指针,数据部分就是vport结构体中的其他成员)10.structhlist_nodehash_node;11.structhlist_nodedp_hash_node;//这是网桥的哈希链表元素12.conststructvport_ops*ops;//这是端口结构体的操作函数指针结构体,结构体里面存放了很多操作函数的函数指针13.14.structpcpu_tstats__percpu*percpu_stats;//vport指向每个cpu的统计数据使用和维护15.16.spinlock_tstats_lock;//自旋锁,防止异步操作,保护下面的两个成员17.structvport_err_statserr_stats;//错误状态(错误标识)指出错误vport使用和维护的统计数字18.structovs_vport_statsoffset_stats;//添加到实际统计数据,部分原因是为了兼容19.};20.21.//端口参数,当创建一个新的vport端口是要传入的参数22.structvport_parms{23.constchar*name;//新端口的名字24.enumovs_vport_typetype;//新端口的类型(端口不仅仅只有一种类型,后面会分析到)25.structnlattr*options;//这个没怎么用到过,好像是从Netlink消息中得到的OVS_VPORT_ATTR_OPTIONS属性26.27./*Forovs_vport_alloc().*/28.structdatapath*dp;//新的端口属于哪个网桥的29.u16port_no;//新端口的端口号30.u32upcall_portid;//和Netlink通信时使用的端口id31.};32.33.//这是端口vport操作函数的函数指针结构体,是操作函数的集合,里面存放了所有有关vport操作函数的函数指针34.structvport_ops{35.enumovs_vport_typetype;//端口的类型36.u32flags;//标识符37.38.//vport端口模块的初始化加载和卸载函数39.int(*init)(void);//加载模块函数,不成功则over40.void(*exit)(void);//卸载端口模块函数41.42.//新vport端口的创建函数和销毁端口的函数43.structvport*(*create)(conststructvport_parms*);//根据指定的参数配置创建个新的vport,成功返回新端口指针44.void(*destroy)(structvport*);//销毁端口函数45.46.//得到和设置option成员函数47.int(*set_options)(structvport*,structnlattr*);48.int(*get_options)(conststructvport*,structsk_buff*);49.50.//得到端口名称和配置以及发送数据包函数51.constchar*(*get_name)(conststructvport*);//获取指定端口的名称52.void(*get_config)(conststructvport*,void*);//获取指定端口的配置信息53.int(*get_ifindex)(conststructvport*);//获取系统接口和设备间的指数54.int(*send)(structvport*,structsk_buff*);//发送数据包到设备上55.};56.57.//端口vport的类型,枚举类型存储58.enumovs_vport_type{59.OVS_VPORT_TYPE_UNSPEC,60.OVS_VPORT_TYPE_NETDEV,61.OVS_VPORT_TYPE_INTERNAL,62.OVS_VPORT_TYPE_GRE,63.OVS_VPORT_TYPE_VXLAN,64.OVS_VPORT_TYPE_GRE64=104,65.OVS_VPORT_TYPE_LISP=105,66._OVS_VPORT_TYPE_MAX67.};第二、网桥模块datapath中涉及到的一些数据结构:[cpp]viewplaincopy1.//网桥结构体2.structdatapath{3.structrcu_headrcu;//RCU调延迟破坏。4.structlist_headlist_node;//网桥哈希链表元素,里面只有next和prev前驱后继指针,数据时该结构体其他成员5.6./*Flowtable.*/7.structflow_table__rcu*table;//这是哈希流表,里面包含了哈希桶的地址指针。该哈希表受_rcu机制保护8.9./*Switchports.*/10.structhlist_head*ports;//一个网桥有多个端口,这些端口都是用哈希链表来链接的11.12.
本文标题:openvswitch源代码分析
链接地址:https://www.777doc.com/doc-6009959 .html