非VXLAN的收发包调用栈
netdev_frame_hook()
     netdev_port_receive()
          ovs_vport_receive()
               ovs_dp_process_packet()
                    (在查表失败后,对于带gso标记的大包,会分片进行upcall)
                    ovs_dp_upcall()                                                        
                    ovs_execute_actions()
                         output: do_output()
                              (通常情况下OVS_CB(skb)->mru为0,直接发送)
                              ovs_vport_send()                                             
                              (在OVS_CB(skb)->mru不为0,(即在output之前还经历了ct,且ct流程进行了分片重组。)且小于出端口的mtu的情况下,进入分片流程)
                              ovs_fragment()                                               
                                   (执行分片)
                                   ip_do_fragment(net, skb->sk, skb, ovs_vport_output);    
                                        (发包,这里代码写的比较绕)
                                        ovs_vport_output()                                 
                                             ovs_vport_send()
                         ct    : ovs_ct_execute()
                              (在进行conntrack的commit或lookup之前,会对分片进行重组,并会设置OVS_CB(skb)->mru的值不为0,为分片中最大的分片的尺寸)
                              handle_fragments()                                           
                              ovs_ct_commit() / ovs_ct_lookup()
 
          ovs_vport_send()
               vport->ops->send(skb) == dev_queue_xmit(skb) == rpl_dev_queue_xmit(skb)
                    (检查包的gso标记,需要分片的情况下进行分片,然后再递归调用dev_queue_xmit()发送分片)
                    skb_gso_segment                                                        
                    
 
总结:
     非VXLAN组网,逻辑基本如下:
          1. 收到多个分片
               1.1. datapath查表失败
                    分片各自上送至用户态,走upcall流程
               1.2. datapath查表成功,或从upcall流程下来
                    开始执行actions
                         while(1)
                              ct               会对分片进行重组,重组后的大包的OVS_CB(skb)->mru会被设置成一个非0值
                                   ovs_vport_send()
                              output           如果没有经过ct,则分片直接被转发,如果经过了ct,则大包还要进行分片操作
                                   ovs_fragment() -> ip_do_fragment() -> ovs_vport_output() -> ovs_vport_send()
                    
          2. 收到带gso标记的大包
               2.1. datapath查表失败
                    先进行分片,然后把分片各自upcall
               2.2. datapath查表成功
                    开始执行actions
                         while(1)
                              ct               直接ct,没有额外操作
                              output           由于OVS_CB(skb)->mru为0,所以直接进入ovs_vport_send()
                                   ovs_vport_send()
                                        在这里检查包的gso标记,然后进行分片,再对各个分片递归调用dev_queue_xmit()发送分片
                                        vport->ops->send == dev_queue_xmit() == rpl_dev_queue_xmit()  
 
     VXLAN组网,逻辑基本如下:
          1:首先是Kernel收到udp报文,走以下流程解封装
               udp_rcv -> __udp4_lib_rcv -> udp_queue_rcv_skb -> encap_rcv -> vxlan_rcv
          2:最终调用 netdev_port_receive -> ovs_vport_receive -> ovs_dp_process_packet
         
          也就是说,VXLAN收包终结之后,不存在分片与重组,而在终结之前的ip报文是否需要重组,则是由kernel负责,不是ovs的责任
          接下来的处理流程都与非VXLAN组网一致了,直至发包
          在VXLAN组网中,发包最终调到 ovs_vport_send() 函数时,vport->ops->send 指针实际调用的函数是 vxlan_xmit
 
          vxlan_xmit -> rpl_vxlan_xmit -> vxlan_xmit_one -> udp_tunnel_xmit_skb -> iptunnel_xmit == rpl_iptunnel_xmit -> ip_local_out == rpl_ip_local_out
          
          在 rpl_ip_local_out 中,类似于 rpl_dev_queue_xmit(),会检查gso标记,如果有gso标记,会将这个ip报文分片然后各片各自发送
          
 

ovs + kernel datapath 的分片与重组流程的更多相关文章

  1. OVS + kernel datapath 的安装

    ***kernel datapath的OVS编译安装 下载源代码 $ git clone https://github.com/openvswitch/ovs.git 准备工具:生成configure ...

  2. OVS+DPDK Datapath 包分类技术

    本文主体内容译于[DPDK社区文档],但并没有逐字翻译,在原文的基础上进行了一些调整,增加了对TSS分类器的详细阐述. 1. 概览 本文描述了OVS+DPDK中的包分类器(datapath class ...

  3. 转自:Tsihang 三层网络设备对于IP报文的分片和重组处理原理

    三层网络设备对于IP报文的分片和重组处理原理 对于网络分片,我一年前就想整理出来,虽然说网络上的资料很多,但是真正掌握精髓的除非真正做过分片程序,不然很难将协议栈整体联系起来理解.这篇文章,包括设计分 ...

  4. openVswitch(OVS)源码分析之工作流程(哈希桶结构体的解释)

    这篇blog是专门解决前篇openVswitch(OVS)源码分析之工作流程(哈希桶结构体的疑惑)中提到的哈希桶结构flex_array结构体成员变量含义的问题. 引用下前篇blog中分析讨论得到的f ...

  5. DPDK IP分片及重组库(学习笔记)

    1 前置知识学习 1.1 MTU MTU是最大传输单元( Maximum Transmission Unit)的缩写,指一个接口无需分片所能发送的数据包的最大字节数.  MTU范围在46 ~ 1500 ...

  6. IP分片与重组详解

    大家对IP数据包头,应该不陌生吧 分片便是与图中圈出来的两个地址有关,本文也是将主要围绕他们展开. 那我们先来了解他们的概念. 标志一个三比特字段遵循与用于控制或识别片段.他们是(按顺序,从高分以低位 ...

  7. Open vSwitch FAQ (一)

    Basic Configuration Q: How do I configure a port as an access port? A: Add "tag=VLAN" to y ...

  8. OpenVSwitch 硬件加速浅谈

    https://zhuanlan.zhihu.com/p/57870521 本文首发SDNLAB. 现代的虚拟化技术使得开发和部署高级网络服务变得更加简单方便.基于虚拟化的网络服务,具有多样性,低成本 ...

  9. openvswith Frequently Asked Questions

    Open vSwitch <http://openvswitch.org> 参考地址:http://git.openvswitch.org/cgi-bin/gitweb.cgi?p=ope ...

随机推荐

  1. Jquery对复选框CheckBox的操作

    checkbox: 多选框 //获取选中值  checkbox:$("#checkbox_id").attr("value"): 多选框checkbox,打勾: ...

  2. OutOfMemoryError内存不足

    java.lang.OutOfMemoryError内存不足错误.当可用内存不足以让Java虚拟机分配给一个对象时抛出该错误. 造成此错误的原因有一下几个: 1.内存中加载的数据量过于庞大,如一次从数 ...

  3. 使用live555 在linux下搭建 rtsp server

    系统环境 Debian 7 x64  / centos 7 x64  都可以 首先去下载源码 http://www.live555.com/liveMedia/public/live555-lates ...

  4. Elasticsearch - 快速入门

    Elasticsearch是基于Apache 2.0开源的实时.分布式.分析搜索引擎,相比Lucene,Elasticsearch的上手比较容易,这篇文章主要纪录Elasticsearch的基本概念和 ...

  5. javascript——数据类型

    在内存中,分为栈.堆.代码段.静态区,为了快速处理复杂的代码,在不同的区间储存不同的数据类型. 数据类型分为初始类型与引用类型,初始类型在栈中存储,变量赋值传值不传址,引用类型在堆中存储,传址不传值. ...

  6. MySQL之使用DDL语句创建表

    一.使用DDL语句创建表 DDL语言全面数据定义语言(Data Define Language) 主要的DDL动词: CREATE(创建).DROP(删除).ALTER(修改) TRUNCATE(截断 ...

  7. DirectFB 之 通过多Window实现多元素处理

    图像 设计 采用多window的方式实现显示,因为每个window可以独立的属性,比如刷新频率,也是我们最关注的 示例 /*************************************** ...

  8. CF798 C. Mike and gcd problem

    /* CF798 C. Mike and gcd problem http://codeforces.com/contest/798/problem/C 数论 贪心 题意:如果一个数列的gcd值大于1 ...

  9. javascript中的apply,call,bind详解

    apply.call 在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向. Jav ...

  10. 最长递增子序列hdu1087

    #include<map> #include<set> #include<list> #include<cmath> #include<queue ...