Open vSwitch之连接管理

连接管理模块是Open vSwitch中非常重要的模块,如果能够熟悉掌握其中的关联结构,对于开发Open vSwitch起到事半功倍的效果。写这篇博客是比较难写的,因为里面涉及层次比较多,生怕梳理不到位,反而误导大家。
Open vSwitch中虽然注释不多,但是它的层次结构非常好而且函数也非常短小。如果阅读过此套代码的人会有比较深入的感触。通过阅读代码可知道,在Open vSwitch中所有函数名、结构体名字定义在头文件中都是接口类,相应的定义到源文件中函数、结构体都是内部类,而且函数都是静态函数。这里需要澄清一下概念,此处提到类并非是C++中的类,而是广义的概念,也就是说Open vSwitch是采用面向对象思想,采用C语言实现的一套软件。
一、结构体
我们还是从结构体入手把,因为结构体是软件的灵魂和桥梁。只有将结构体分析透彻才能梳理出整个软件的架构层次。

外部流结构(外部接口):

流对象(外部接口):

内部流结构(内部管理接口):

从上面可知,前两个是对外接口 (定义在头文件中),最后一个是内部接口,用于实际管理。其中第二个结构的成员机会都是函数指针,从面向对象的角度来说,这个结构对应着抽象类 (或者接口) ,主要目的是实现多态。三者是如何管理是如何关联起来的呢? 是通过一个非常短的函数 new_fd_stream,如下所示:

针对上面两个函数需要说明三点:
1、stream_fd_class 是内部静态全局常量,类型是 stream_class。通过定义可知,内部函数指针实际指向的是流操作相关函数,例如: send,recv ,close等。换句话说,当进行真正的 socket数据传输过程中主要是通过下面的函数。函数指针 open为什么NULL?? 没有open函数怎么可能连接起来呢??

2、连接socket套接字保存在内部流管理fd中并非在外部流管理中。
3、函数返回并非是内部流管理而是外部流管理。当进行最底层数据处理时候,在转换成内部流管理,可以参考一下fd_send函数。

这个在介绍一个全局stream管理结构,用面向对象思想这个结构体是抽象类(接口)的实现。此结构体是也静态局部常量,主要用于连接方式管理,例如tcp连接,unix连接,ssl方式连接,甚至跨平台window方式连接。

这里我们在讲tcp_stream_class展开看一下内部结构:

当我看到tcp_stream_class定义的时候,也是很奇怪,为什么tcp_stream_class只定义了open,定义没有其他函数呢??
但是当tcp_stream_class和stream_fd_class整合到一起,除了run和run_wait外其他函数指针都定义了,貌似这两者存在着某种关联??我只能深入梳理代码,去验证我的猜测。

二、连接创建
上面数据结构主要是用于Open vSwitch交换机与控制器连接(Socket连接),下面我们来分析一下,Open vSwitch是如何一步一步与控制器建立起来的socket连接。

下图是我通过Source Insight截取出来的函数调用关系。函数层次比较深入,有些地方讲解可能不够深入或者层次不清晰,因此对于这部读者需要自己深入看一下代码加深理解。

第一部分讲解是Open vSwitch中最底层socket连接管理层次,对于上层应用来说这个层次是不可见的。也就是说Open vSwitch不是直接操作stream类的,而是通过ofconn管理,或者在深一层是通过vconn管理。下面是函数流程图,针对此流程图有两点说明:
1)红色线代表返回上层函数,蓝色线表示回到最顶层函数。
2)由于函数层次较深,图中会有向右走向的函数,纯粹是为了节省篇幅

对于SDN 来说,理论上一个控制器可以管理多个交换机,一个交换机也可以被多个控制器管理。因此Open vSwitch在启动过程中,根据配置会主动连接每个控制器。

ofproto_set_controllers à add_controller 创建rconn 和ofcon,并且将 rconn挂在ofconn 中 à rconn_connect àreconnect à vconn_open 这个函数中会根据连接类型 (tcp连接,unix 连接等)在抽象类 vconn_classes中查找对应的实例。找到实例之后调用对应的 open函数,开始创建socket以及出事 tream流对象等一系列动作,最后返回到函数 connmgr_set_controller判断是否还有其他的控制器需要连接,如果有则再次执行此流程,如果没有则结束。

上面的流程比较复杂,需要我们认真去看一下代码,此处只是起到“抛砖引玉”的效果。最后展示一下数据结构关系图:

在ovs数据结构中,有很多这样的数据结构,比如说有结构 A,B ,结构B包含在结构 A中,对外使用的是结构B。类似代码中 struct vconn_stream,struct vconn 对外使用的是 struct vconn。至于ovs 为什么要这样设计的原因,我不是很清楚,只能猜测是为了封装和抽象。


  • 声明本文来自 SDNLAB

猜你喜欢

转载自blog.csdn.net/yueyihua/article/details/51027932
今日推荐