Sockmap与基本原理
,代理转发行为拉长了网络传输路径,相对于直连增加了2次内核态和用户态之间的切换、2次内核态和用户态之间的数据拷贝、2次网络协议栈的处理以及1次用户态处理,因此代理转发相比直连大大的降低了网络性能(提高了时延,降低了带宽)。 sockmap就是在这个背景下产生的,其目的就是提供一种加速本机内部TCP socket之间数据转发的机制。 机制1 socket数据转发卸载 简介 如图2.1,通常用户态程序(如代理程序)需要通过系统调用sys_read从一个socket中读取数据到用户态,这个过程涉及到2次上下文切换(用户态->内核态->用户态)和1次内核态到用户态的数据拷贝;用户态程序对从socket中读取的数据进行一系列处理后,再通过系统调用sys_write将处理后的数据写入到另一个socket中去,这个过程涉及到2次上下文切换(用户态->内核态->用户态)和1次用户态到内核态的数据拷贝。ap最初的版本提供了一种在本机TCP socket之间直接进行skb(struct sk_buff,其表示一个包含包头的数据包,后续均简称为skb)转发的机制。如图2.2,这种机制允许将原先图2.1中的用户态处理部分的逻辑卸载到内核BPF程序中进行处理,处理后的数据包skb直接在内核态中转发到另一个socket中去进行数据包的发送。整个过程无需的用户态内核态之间上下文切换,也无需任何用户态内核态之间的数据拷贝,大大缩短了数据转发路径。 关联的BPF程序 针对本机制,sockmap提供了两种BPF程序类型: 1. BPF_SK_SKB_STREAM_VERDICT 该类型的BPF程序根据用户的逻辑对数据进行处理和仲裁,其返回值(有如下三种)决定了源sock中数据的具体转发行为: 1.1 SK_PASS 该行为表示数据将按图2.1的方式被用户态程序接收处理并再发送到目的sock中。 1.2 SK_REDIRECT 该行为表示数据将按图2.2的方式在内核态中直接被BPF程序处理并发送到目的sock中。 1.3 SK_DROP 该行为表示数据将被直接丢弃。 2. BPF_SK_SKB_STREAM_PARSER 该类型的BPF程序不可单独使用,必须与BPF_SK_SKB_STREAM_VERDICT程序搭配使用,其用于确定一条完整消息的边界。通常数据流协议,在协议头中会指定playload有几个字节,然后通过底层tcp读取完协议头header和完整的payload后,才形成一条完整的消息记录。当BPF_SK_SKB_STREAM_VERDICT程序不能自行确定一条完整的消息长度时,就需要该BPF程序来确定是否读取到一条完整消息的尾部。
大多数情况下,BPF_SK_SKB_STREAM_VERDICT程序要么是可以自行确定消息的边界要么只是从skb中获取一些元数据例如IP地址。这时,该类型的BPF程序一般就直接返回SKB长度即可,如下。在内核5.10版本之后,这种情形的BPF_SK_SKB_STREAM_PARSER程序可以省略,仅使用BPF_SK_SKB_STREAM_VERDICT即可。 (编辑:云计算网_泰州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |