Open vSwitch(OvS)源代码分析之工作流程(数据包处理)

sdn-Open-vSwitch(OvS)源代码分析之工作流程(数据包处理)

上篇分析到数据包的收发,这篇开始着手分析数据包的处理问题。在Open vSwitch中数据包的处理是其核心技术,该技术分为三部分来实现:第一、根据skb数据包提取相关信息封装成key值;第二、根据提取到key值和skb数据包进行流表的匹配;第三、根据匹配到的流表做相应的action操作(若没匹配到则调用函数往用户空间传递数据包);其具体的代码实现在 datapath/datapath.c 中的,函数为: void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb);当接受到一个数据包后,自然而然的就应该是开始对其进行处理了。

所以其实在上篇的《Open vSwitch(OvS)源代码分析之工作流程(收发数据包)》中的接受数据包函数:void ovs_vport_receive(struct vport *vport, struct sk_buff *skb)中已有体现,该函数在最后调用了ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb);来把数据包传递到该函数中去进行处理。也由此可见所有进入到Open vSwitch的数据包都必须经过ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb);函数的处理。所以说ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb);是整个Open vSwitch的中间枢纽,是Open vSwitch的核心部分。

对于ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb);的重要性已经解释的非常清楚,紧接着就应该分析该函数源代码了,在分析源代码之前还是得提醒下,其中涉及到很多数据结构,如果有些陌生可以到Open vSwitch(OvS)源代码分析之数据结构中进行查阅,最好能先大概的看下那文章,了解下其中的数据结构,对以后分析源代码有很大的帮助。

下面来分析几个ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb);函数中涉及到但在Open vSwitch(OvS)源代码分析之数据结构又没有分析到的数据结构:

第一个、是数据包的统计结构体,是CPU用来对所有数据的一个统计作用:

第二、是数据包发送到用户空间的参数结构体,在匹配流表没有成功时,数据将发送到用户空间。而内核空间和用户空间进行数据交互是通过netLinks来实现的,所以这个函数就是为了实现netLink通信而设置的一些参数:

下面是来分析ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb);函数的实现源代码:

上面就是Open vSwitch的核心部分,所有的数据包都要经过此函数进行逻辑处理。这只是一个逻辑处理的大体框架,还有一些细节(key值得提取,流表的匹配查询,数据传输到用户空间,根据流表执行相应action)将在后面分析。当把整个Open vSwitch的工作流程梳理清晰,会发现这其实就是Open vSwitch的头脑部分,所有的逻辑处理都在里实现,所以我们自己添加代码时,这里往往也是个不错的选择。

如果看了前面那篇《Open vSwitch(OvS)源代码分析之工作流程(收发数据包)》,那么应该记得其中也说到了可以在收发函数中添加自己代码,因为一般来说收发函数也是数据包的必经之地(发送函数可能不是)。那么怎么区分在哪里添加自己代码合适呢?

其实在接受数据包函数中添加自己代码和在这里的逻辑处理函数中添加自己代码,没有多大区别,因为接受函数中没有做什么处理就把数据包直接发送打逻辑处理函数中去了,所以这两个地方添加自己代码其实是没什么区别的。但是从习惯和规范来说,数据包接受函数只是根据条件控制数据包的接受,并不对数据包进行逻辑上的处理,也不会对数据包进行修改等操作。而逻辑处理函数是会对数据包进行某些逻辑上的处理。(最明显的是修改数据包内的数据,一般来说接受数据包函数中是不会对数据包内容修改的,但逻辑处理函数则有可能会去修改的)。

而在数据包发送函数中添加自己代码和逻辑函数中添加自己代码也有些区别,数据包发送函数其性质和接受函数一样,一般不会去修改数据包,而仅仅是根据条件判断该数据包是否发送而已。

那下面就逻辑处理函数中添加代码来举例:

假若要把某个指定的IP主机上发来的ARP数据包进行处理,把所有的请求数据包变成应答数据包,原路返回。这里最好就是把自己的代码添加到逻辑处理函数中去(如果你要强制的添加到数据包接受函数中去也可以),因为这里要修改数据包的内容,是一个逻辑处理。具体实现:可以在key值提取前对数据包进行判断,看是否是ARP数据包,并且是否是指定IP主机发来的。若不是,交给系统去处理;若是,则对Mac地址和IP地址进行交换,并且把请求标识变成应答标识;最后调用发送函数从原来的端口直接发送出去。这只是一个简单的应用,旨在说明逻辑处理代码最好添加到逻辑处理函数中去。如果要处理复杂的操作也是可以的,比如定义自己的流表,然后然后屏蔽掉系统的流表查询,按自己的流表来操作。这就是一个对Open vSwitch比较大的改造了,流表、action、流表匹配等这些Open vSwitch主要功能和结构都要自己去定义实现完成。

以上分析得就是Open vSwitch的核心部分,当然了只是一个大体框架而已,后续将会逐步完善。

如有不正确之处,望大家指正,谢谢!

 
 
 
转载自:CSDN,http://blog.csdn.net/yuzhihui_no1/article/details/39378195


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

登录后才可以评论

SDNLAB君 发表于14-11-03
4