网络数据包分析——网卡Offload

1. 网卡收发包的offload

为了解决性能问题,就产生了TOE技术(TCP offload engine),将TCP连接过程中的相关计算工作转移到专用硬件上(比如网卡),从而释放CPU资源。网卡的offload是指将CPU对数据包的一些处理操作转到硬件网卡上进行,由此释放出CPU的计算资源。offload也被称为硬件卸载。从2012年起,offload技术开始在网卡上使用。

发展至今,网卡上已经支持多种形式的offload。目前,在收发方向上,网卡各自支持不同的offload,下面将分别展开描述。本文所描述的offload特性,主要是指将原本在协议栈中进行的IP分片、TCP分段、重组、checksum校验等操作,转移到网卡硬件中进行,降低系统CPU的消耗,提高处理性能。

1.1. 网络分片技术

1.1.1. MTU

最大传输单元,指一种通信协议的某一层上面所能通过的最大数据包大小(以字节为单位)。

在以太网通信中,MTU规定了经过网络层封装的数据包的最大长度。例如,若某个接口的MTU值为1500,则通过此接口传送的IP数据包的最大长度为1500字节。

1.1.2. IP分片

当IP层需要传送的数据包长度超过MTU值时,则IP层需要对该数据包进行分片,使每一片的长度小于或等于MTU值。在分片过程中,除了对payload进行分片外,数据包的IP首部也需要进行相应的更改:

分片DF_MF标记位

  • 将identifier字段的值复制给每个分片;
  • 将分片数据包的Flags中的DF位置为0;否则为1;
  • 除最后一个分片之外的其他分片(非最后分片),将MF位置为1;最后一个分片MF为0;
  • 将Fragment Offset字段设置正确的值。

1.1.3. MSS

最大分段长度,TCP数据包每次能够传输的最大数据分段长度,在TCP协议的实际实现中,MSS往往用MTU-(IP Header Length + TCP Header Length)来代替。在TCP通信建立连接时,取两端提供的MSS的最小值作为会话的MSS值。由于TCP分段有MSS值的限制,通常情况下TCP数据包经IP层封装后的长度不会大于MTU,因此一般情况下,TCP数据包不会进行IP分片。

1.2. 发送方向

1.2.1. VLAN Tag的插入

   VLAN虽然只有四个字节,却可以实现以太网的隔离。其基本使用方式机在以太网中报文中增加一个4字节的802.1q Tag,也称为VLAN Tag。VLAN Tag的插入和过滤剥离均可以通过网卡来完成。在发送方向,需要进行VLAN的插入操作。

1.2.2. LSO(large-segment-offload)

   计算机网络上传输的数据基本单位是离散的网包,其大小的限制为MTU(Maximum Transmission Unit)的大小,一般是1518字节。比如我们想发送很多数据出去,经过os协议栈的时候,会自动帮你拆分成几个不超过MTU的网包。然而,这个拆分是比较费CPU计算资源的。把这些简单重复的操作 offload 到网卡上就是LSO。
   在发送数据超过 MTU 限制的时候(太容易发生了),OS 只需要提交一次传输请求给网卡,网卡会自动的把数据拿过来,然后进行切片,并封包发出,发出的网包不超过 MTU 限制。

1.2.3. TSO(Tcp-segment-offload)/UFO(udp-fragmentation-offload)分片

    对于从应用层获取的比较大的数据包,需要根据下层网络的报文大小限制,将其切分为较小的分片发送。TCP报文使用TSO,而UDP报文则使用UFO,都属于LSO的范畴。如果硬件支持 TSO功能,同时也需要硬件支持的TCP校验计算和分散/聚集 (Scatter Gather) 功能。

1.2.4. GSO(generic-segmentation-offload)分片

   相对于TSO和UFO,GSO是一种更通用的机制。其基本思想就是把数据分片的操作尽可能的向底层推迟直到数据发送给网卡驱动之前,并先检查网卡是否支持TSO或UFO机制,如果支持就直接把数据发送给网卡,否则的话就软件进行分片后再发送给网卡,以此来保证最少次数的协议栈处理,提高数据传输和处理的效率。

1.2.5. Checksum

    Checksum是用于校验目的的一组数据项的和,用于在远距离通信中保证数据的完整性和准确性。在Ethernet、IPV4、UDP、TCP、SCTP各个协议层中都有checksum字段。IPV6头部没有checksum字段,因此不需要进行checksum计算。在收发方向上,均需要对checksum进行支持。由于checksum需要整个报文参与计算,逐包计算对于CPU来说是个不小的开销。
   在发送侧,需要计算计算协议的checksum,将其写入合适的位置。原理上,网卡在设计之初就需要依赖软件做额外设置,软件需要逐包提供发送侧的上下文状态描述符,这段描述符通过Pcie总线写入到网卡设备内,帮助网卡进行checksum计算。实际上是将传输层的一部分工作交给了硬件完成,以节约系统的CPU资源。

1.3. 接收方向

1.3.1. VLAN Tag的过滤(filtering)剥离(stripping)

    在收包时,需要完成VLAN Tag的过滤和剥离操作。过滤的实现方式是设置VLAN过滤表,无法在过滤表中匹配的报文会被直接丢弃。VLAN Tag的剥离也是由网卡来完成的。此时网卡会在硬件描述符中设置两个域,包含此包是否曾被剥离了VLAN Tag,以及被剥离的VLAN Tag,并通知驱动软件。

1.3.2. LRO(large-receive-offload)/GRO(generic-receive-offload)

   与LSO对应, 收方向上网卡会将接受到的多个数据包分片聚合成一个大的数据包,然后上传给协议栈处理。GRO对LRO有了一些改进,更加通用,目前主流的网卡所使用的都是GRO的offload。

1.3.3. Checksum

   在接收方向,通过设置端口配置,强制对所有达到的数据报文进行检测,即判断哪些包的checksum是错误的,对于出错的包可直接进行丢弃。

1.3.4. RSS(Receive-side-scaling)

   RSS是网卡上一种用于将流量均匀分散到不同的队列上的技术。简而言之,就是首先在硬件上根据关键字进行哈希值的计算,再由哈希值确定队列。不同的数据包类型对应不同的数据包类型,如IPV4包对应四元组,使用者甚至可以修改包类型对应的关键字以满足不同的要求。
具备多个RSS队列的网卡,可以将不同的网络流分成不同的队列,再将这些队列分配到多个CPU核心上进行处理,从而将负荷分散,充分利用多核处理器的能力,提交数据接收的能力和效率。

1.3.5. Flow Director

   Flow Director技术是Intel公司提出的根据包的精确字段匹配,将其分配到某个特定队列的技术。如果说RSS主要用来做负载均衡的话,Flow Director则是用来做精确的流导向。
Flow Director的工作方式为:网卡上存储了一张Flow Director的表,它记录了需要匹配关键字段的关键字以及匹配后的动作。驱动负责操作这张表。网卡收到数据包之后,根据关键字查询这张表,匹配后按照表项中的动作来进行处理。

1.4. 实践操作

   值得注意的是,目前常用的抓包工具如tcpdump、wireshark等大部分都是从协议栈中捕获数据包,而网卡的offload特性会将数据包的分片、重组等工作转移到协议栈以下的硬件层面 进行,因此在开启TSO、GRO等机制的情况下,我们使用抓包工具抓取到的数据包往往不能真实反应链路上实际的数据帧, 给网络流量特征的分析造成不利影响。针对这些情况,可以选择关闭网卡offload的相关选项,或者在链路的其他节点进行抓包。

可以使用如下命令来关闭对应的参数:

#ethtool –K 设备名 模式名(缩写)on/off
[root@local ~]# /usr/sbin/ethtool -K eth1 gro off
[root@local ~]# /usr/sbin/ethtool -K eth1 tso off
[root@local ~]# /usr/sbin/ethtool -K eth1 lro off
[root@local ~]# ethtool -k eth1
Features for eth1:
rx-checksumming: on
tx-checksumming: on
scatter-gather: off
tcp-segmentation-offload: off
udp-fragmentation-offload: off
generic-segmentation-offload: on
generic-receive-offload: off
large-receive-offload: off
ntuple-filters: off
receive-hashing: off
[root@Therez_web_Server ~]# ethtool -K eth1 tx off
Actual changes:
rx-checksumming: off
tx-checksumming: off
[root@Therez_web_Server ~]# ethtool -k eth1
Features for eth1:
rx-checksumming: off
tx-checksumming: off
scatter-gather: off
tcp-segmentation-offload: off
udp-fragmentation-offload: off
generic-segmentation-offload: on
generic-receive-offload: off
large-receive-offload: off
ntuple-filters: off
receive-hashing: off

————————————————

部分参考 网卡收发包的offload

发表评论

邮箱地址不会被公开。 必填项已用*标注