ovs + kernel datapath 的分片与重组流程

非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报文分片然后各片各自发送

时间: 2024-11-29 07:55:43

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

OVS + kernel datapath 的安装

***kernel datapath的OVS编译安装 下载源代码 $ git clone https://github.com/openvswitch/ovs.git 准备工具:生成configure文件 GNU make $ make --version 一个C语言编译器,GCC 4.6以上,Clang 3.4以上 $ gcc --version libssl $ apt-get isntall libssl1.0.0 libcap-ng0 $ apt-get install libcap-n

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

这篇blog是专门解决前篇openVswitch(OVS)源码分析之工作流程(哈希桶结构体的疑惑)中提到的哈希桶结构flex_array结构体成员变量含义的问题. 引用下前篇blog中分析讨论得到的flex_array结构体成员变量的含义结论: struct { int element_size; // 这是flex_array_part结构体存放的哈希头指针的大小 int total_nr_elements; // 这是全部flex_array_part结构体中的哈希头指针的总个数 int e

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

三层网络设备对于IP报文的分片和重组处理原理 对于网络分片,我一年前就想整理出来,虽然说网络上的资料很多,但是真正掌握精髓的除非真正做过分片程序,不然很难将协议栈整体联系起来理解.这篇文章,包括设计分片原理图,耗时一小时完成,算是记录一点理解. 三层网络设备,即能够基于IP头信息对报文进行识别和处理的网络设备,在转发IP报文的时候,经常会遇到来自上层的数据包过长,从而导致打上MAC头的帧不符合IEEE802.3标准规定的最大帧长,造成不能被转发和对端解析的问题.这样就需要在三层进行分片,将过长的

IP数据包的分片与重组过程

一.IP分片 (一)IP分片的原理: 分片和重新组装的过程对传输层是透明的,其原因是当IP数据报进行分片之后,只有当它到达下一站时,才可进行重新组装,且它是由目的端的IP层来完成的.分片之后的数据报根据需要也可以再次进行分片.    IP分片和完整IP报文差不多拥有相同的IP头,ID域对于每个分片都是一致的,这样才能在重新组装的时候识别出来自同一个IP报文的分片.在IP头里面,16位识别号唯一记录了一个IP包的ID(ipid),具有同一个ID的IP分片将会重新组装:而13位片偏移则记录了某IP片

OVS+DPDK Datapath 包分类技术

// editing... please wait for a java time // editing... please wait for a java time // editing... please wait for a java time // editing... please wait for a java time // editing... please wait for a java time // editing... please wait for a java tim

Open vSwitch FAQ (一)

Basic Configuration Q: How do I configure a port as an access port? A: Add "tag=VLAN" to your "ovs-vsctl add-port" command. For example, the following commands configure br0 with eth0 as a trunk port (the default) and tap0 as an access

Lwip IP包分片重组

1. 开发环境 操作系统:SylixOS 编程环境:RealEvo-IDE3.1 硬件平台:AT9x25开发板 2. 技术实现 SylixOS系统使用的网络协议栈是Lwip协议栈.Lwip是Light Weight (轻型)IP协议,有无操作系统的支持都可以运行.Lwip实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用,它只需十几KB的RAM和40K左右的ROM就可以运行,这使Lwip协议栈适合在低端的嵌入式系统中使用. Lwip协议栈主要关注的是怎么样减少内存的使用和代码的大小

[uboot] uboot启动kernel篇(二)——bootm跳转到kernel的流程

一.bootm说明 bootm这个命令用于启动一个操作系统映像.它会从映像文件的头部取得一些信息,这些信息包括:映像文件的基于的cpu架构.其操作系统类型.映像的类型.压缩方式.映像文件在内存中的加载地址.映像文件运行的入口地址.映像文件名等. 紧接着bootm将映像加载到指定的地址,如果需要的话,还会解压映像并传递必要有参数给内核,最后跳到入口地址进入内核. 这里的描述参考(http://blog.chinaunix.net/uid-20799298-id-99666.html) 需要打开的宏

ip分片重组 ip_defrag

在ip_local_deliver中,如果检测到是分片包,则需要进行分片重组: ip_local_deliver |-->ip_is_fragment //判断是否为分片包 |-->ip_defrag //分片缓存&重组 |-->ip_find //查找ipq |-->ip_frag_find //查找frag_queue |-->ip_defrag_queue //分片接收组合 |-->ip_frag_reasm //接收完整的分片组成新的ip包 1 /* 2