2015年10月14日
本文说明了网卡,IP层,TCP层,UDP层的校验和功能,以及异同点。
网卡校验和
高级的网卡(e1000e等千M网卡)的接收,发送的校验和的计算方法是CRC32。
Refs:http://www.wireshark.org/docs/wsug_html_chunked/ChAdvChecksums.html
http://www.intel.com/content/dam/doc/manual/pci-pci-x-family-gbe-controllers-software-dev-manual.pdf
可以使用ethtool查看网卡的校验功能,rx-checksumming是接收端的校验功能,tx-checksumming是发送端的校验功能:
# ethtool -k eth0
Offload parameters for eth0:
rx-checksumming: on
tx-checksumming: on
scatter-gather: on
tcp-segmentation-offload: on
udp-fragmentation-offload: off
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: off
IP校验和
校验和只对头部进行,不包括数据部分。
发送IP包, 计算checksum:
(1)把IP数据报的首部校验和字段设置为0。
(2)把首部看成以16位为单位的数字组成,依次进行二进制反码求和。
(3)把得到的结果存入校验和字段中。
接收IP包,验证checksum:
(1)把首部看成以16位为单位的数字组成,依次进行二进制反码求和,包括校验和字段。
(2)检查计算出的校验和的结果是否为全1。
(3)如果全1,校验是和正确。否则,校验和就是错误的,协议栈要抛弃这个数据包。但不生成差错报文,由上层去发现丢失的数据报并进行重传。
Refs:
http://tools.ietf.org/html/rfc791
UDP校验和
校验和即覆盖头部,也覆盖数据部分。UDP校验和是可选的,而TCP校验和是必须的。
发送包, 计算checksum:
算法和IP头部的校验和计算方法类似:二进制反码求和。但有下面两个区别:
1) 总长度如果是奇数,则自动补齐,并自动填充为0. 填充的部分不发送出去。
2)添加12个字节的伪头部。源地址(4个字节),目的地址(4个字节),0(1个字节),udp协议号(1个字节),udp头部中长度字段值(2个字节)。
如果校验和字段是0,表示不需要计算校验和。
接收包, 验证checksum:
验证checksum是根据udp头部中的length字段值所指向的数据长度进行校验,如果length字段值大于实际的数据长度,那么包在校验前会被丢弃。如果length字段值小于实际的数据长度,则需要裁减数据,并校验。
TCP校验和
校验和即覆盖头部,也覆盖数据部分。TCP校验和是必须的。也包含了12个字节的伪头部。
http://docs.gz.ro/node/282
TCP offload engine or TOE is a technology used in networkinterface cards (NIC) to offload processing of the entire TCP/IP stack to thenetwork controller. It is primarily used with high-speed network interfaces,such as gigabit Ethernet and 10 Gigabit Ethernet, where processing overhead ofthe network stack becomes significant.
The term, TOE, is often used to refer to the NIC itself, although circuit boardengineers may use it to refer only to the integrated circuit included on thecard which processes the TCP headers. TOEs are often suggested as a way toreduce the overhead associated with IP storage protocols such as iSCSI and NFS.Read more about this on wikipedia.
Linux doesn't support TOE by default because of many reasonsmentioned here.
But even if TOE is not suitable, at least for now, there are other settingsthat could improve your network (especially if you use it for iSCSI). So readon and remember: in most of the cases, these settings must be ON but you haveto test and see what is suitable for your environment. Enjoy!
Most of these offload features are configured using the ethtool tool.In order to check which features are set, you can use the -k parameter.Also, in order to disable/enable, use -K or --offload parameteralong with the desired features.
Display: ethtool -kethX
Enable (recommended): ethtool -K ethX rx on tx on
Disable: ethtool -KethX rx off tx off
root@pluto:~# ethtool -k eth2
Features for eth2:
rx-checksumming: off
tx-checksumming: on
tx-checksum-ipv4: off [fixed]
tx-checksum-unneeded: off [fixed]
tx-checksum-ip-generic: on
tx-checksum-ipv6: off [fixed]
tx-checksum-fcoe-crc: off [fixed]
tx-checksum-sctp: off [fixed]
scatter-gather: on
tx-scatter-gather: on
tx-scatter-gather-fraglist: off [fixed]
tcp-segmentation-offload: on
tx-tcp-segmentation: on
tx-tcp-ecn-segmentation: off [fixed]
tx-tcp6-segmentation: off [fixed]
udp-fragmentation-offload: off [fixed]
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: off [fixed]
rx-vlan-offload: on
tx-vlan-offload: on [fixed]
ntuple-filters: off [fixed]
receive-hashing: off [fixed]
highdma: off [fixed]
rx-vlan-filter: on [fixed]
vlan-challenged: off [fixed]
tx-lockless: off [fixed]
netns-local: off [fixed]
tx-gso-robust: off [fixed]
tx-fcoe-segmentation: off [fixed]
fcoe-mtu: off [fixed]
tx-nocache-copy: on
loopback: off [fixed]
root@pluto:~# ethtool --offload eth2 rx off tx off
Actual changes:
tx-checksumming: off
tx-checksum-ip-generic: off
scatter-gather: off
tx-scatter-gather: off [requested on]
tcp-segmentation-offload: off
tx-tcp-segmentation: off [requested on]
generic-segmentation-offload: off [requested on]
root@pluto:~# ethtool --offload eth2 rx on tx on
Actual changes:
rx-checksumming: on
tx-checksumming: on
tx-checksum-ip-generic: on
scatter-gather: on
tx-scatter-gather: on
tcp-segmentation-offload: on
tx-tcp-segmentation: on
generic-segmentation-offload: on
This is useful to reduce CPU overhead and it is also called Large SegmentOffload (LSO).
In order to enable/disable TCP segmentation offload, you must use ethtool commandwith tso option:
Display: ethtool -k ethX | grep tcp-segmentation
Enable (recommended): ethtool -K ethX tso on
Disable: ethtool -K ethX tso off
root@pluto:~# ethtool -K eth2 tso off
root@pluto:~# ethtool -k eth2 | grep segmentation
tcp-segmentation-offload: off
tx-tcp-segmentation: off
tx-tcp-ecn-segmentation: off [fixed]
tx-tcp6-segmentation: off [fixed]
generic-segmentation-offload: on
tx-fcoe-segmentation: off [fixed]
root@pluto:~# ethtool -K eth2 tso on
root@pluto:~# ethtool -k eth2 | grep segmentation
tcp-segmentation-offload: on
tx-tcp-segmentation: on
tx-tcp-ecn-segmentation: off [fixed]
tx-tcp6-segmentation: off [fixed]
generic-segmentation-offload: on
tx-fcoe-segmentation: off [fixed]
Scatter and Gather (Vectored I/O) is a concept that was primarily used in harddisks and it enhances large I/O request performance, if supported by thehardware.
To manipulate this feature, you must use the same ethtool commandwith the following parameter:
Display: ethtool -kethX | grep scatter-gather
Enable (recommended): ethtool -K ethX sg on
Disable: ethtool -K ethX sg off
root@pluto:~# ethtool -k eth2 | grep scatter-gather
scatter-gather: on
tx-scatter-gather: on
tx-scatter-gather-fraglist: off [fixed]
root@pluto:~# ethtool -K eth2 sg off
Actual changes:
scatter-gather: off
tx-scatter-gather: off
tcp-segmentation-offload: off
tx-tcp-segmentation: off [requested on]
generic-segmentation-offload: off [requested on]
root@pluto:~# ethtool -K eth2 sg on
Actual changes:
scatter-gather: on
tx-scatter-gather: on
tcp-segmentation-offload: on
tx-tcp-segmentation: on
generic-segmentation-offload: on
This feature is related to TSO so it is advisable to enable them together. Itcan be done with ethtool command also:
Display: ethtool -k ethX | grepgeneric-segmentation-offload
Enable (recommended): ethtool -K ethX gso on
Disable: ethtool -K ethX gso off
root@pluto:~# ethtool -K eth2 gso off
root@pluto:~# ethtool -k eth2 | grep generic-segmentation-offload
generic-segmentation-offload: off
root@pluto:~# ethtool -K eth2 gso on
root@pluto:~# ethtool -k eth2 | grep generic-segmentation-offload
generic-segmentation-offload: on
To avoid any extra search from your part, if you have offload features enabledand you see cksum incorrect in tcpdump output,without any packet errors and your network is working properly: it is nothingto worry about because the checksum is actually calculated on the networkadapter and the tcpdump is showing the checksum calculated on kernel level.Read more here if you are curious.
ethtool 常用命令如下,比如对eth0的操作:
ethtool eth0 //查询ethx网口基本设置,其中 x 是对应网卡的编号,如eth0、eth1等等
ethtool –h //显示ethtool的命令帮助(help)
ethtool –ieth0 //查询eth0网口的相关信息
ethtool –deth0 //查询eth0网口注册性信息
ethtool –reth0 //重置eth0网口到自适应模式
ethtool –Seth0 //查询eth0网口收发包统计
ethtool –s eth0[speed 10|100|1000] [duplex half|full] [autoneg on|off] //设置网口速率10/100/1000M、设置网口半/全双工、设置网口是否自协商
我这里主要想发掘一下ethtool -k 相关的内容,以下命令在ubuntu 14.04上亲测:
1、rx-checksumming: off
接收侧硬件校验和计算,如能设置为on,表示网卡支持该特性,命令: ethtool -K eth0 rx-checksum on|off
2、tx-checksumming:on
发送侧硬件校验和计算,如能设置为on,表示网卡支持该特性,命令: ethtool -K eth0 tx-checksum-ip-generic on|off
3、scatter-gather:on
分散/聚集 (Scatter Gather) 功能,是网卡要支持TSO的必要条件之一。
4、tcp-segmentation-offload: on
简称TSO,是一种利用网卡对TCP数据包分片,减轻CPU负荷的一种技术,有时也被叫做 LSO (Large segment offload) ,TSO是针对TCP的,UFO是针对UDP的。如果硬件支持 TSO功能,同时也需要硬件支持的TCP校验计算和分散/聚集 (Scatter Gather) 功能。命令: ethtool -K eth0 tso on|off
在不支持TSO的网卡上,TCP层向IP层发送数据会考虑mss,使得TCP向下发送的数据可以包含在一个IP分组中而不会造成分片, mss是在TCP初始建立连接时由网卡MTU确定并和对端协商的,所以在一个MTU=1500的网卡上,TCP向下发送的数据不会大于min(mss_local, mss_remote)-ip头-tcp头。
网卡支持TSO时,TCP层会逐渐增大mss(总是整数倍数增加),当TCP层向下发送大块数据时,仅仅计算TCP头,网卡接到到了IP层传下的大数据包后自己重新分成若干个IP数据包,添加IP头,复制TCP头并且重新计算校验和等相关数据,这样就把一部分CPU相关的处理工作转移到由网卡来处理。
5、udp-fragmentation-offload: off
简称UFO,是网卡对udp提供的类似TSO的技术。命令:ethtool -K eth0 ufo on | off
在我的网卡上不支持这个特性,所以命令执行失败是这样的:
root@ubuntu:~#ethtool -K eth0 ufo on
Cannot changeudp-fragmentation-offload
Could not changeany device features
6、generic-segmentation-offload: on
简称GSO,它比TSO更通用,基本思想就是尽可能的推迟数据分片直至发送到网卡驱动之前,此时会检查网卡是否支持分片功能(如TSO、UFO), 如果支持直接发送到网卡,如果不支持就进行分片后再发往网卡。这样大数据包只需走一次协议栈,而不是被分割成几个数据包分别走,这就提高了效率。命令: ethtool -K eth0 gso on | off
7、large-receive-offload: off
简称LRO,通过将接收到的多个TCP数据聚合成一个大的数据包,然后传递给网络协议栈处理,以减少上层协议栈处理开销,提高系统接收TCP数据包的能力。
8、generic-receive-offload: on
简称GRO,基本思想跟LRO类似,克服了LRO的一些缺点,更通用。后续的驱动都使用GRO的接口,而不是LRO。
附:
RSS(Receive Side Scaling),是一项网卡的新特性,俗称多队列。具备多个RSS队列的网卡,可以将不同的网络流分成不同的队列,再分别将这些队列分配到多个CPU核心上进行处理,从而将负荷分散,充分利用多核CPU的能力。
对于网络安全来说,网络传输数据包的捕获和分析是个基础工作,绿盟科技研究员在日常工作中,经常会捕获到一些大小远大于MTU值的数据包,经过分析这些大包的特性,发现和网卡的offload特性有关,本文对网卡Offload技术做简要描述。
最大传输单元,指一种通信协议的某一层上面所能通过的最大数据包大小(以字节为单位)。
在以太网通信中,MTU规定了经过网络层封装的数据包的最大长度。例如,若某个接口的MTU值为1500,则通过此接口传送的IP数据包的最大长度为1500字节。
小编注:对于普通用户来说,如果你优化过迅雷的下载速度,可能通过这篇文章《合理设置MTU,提升下载速度》,对MTU的基础知识有所了解。
IP分片
当IP层需要传送的数据包长度超过MTU值时,则IP层需要对该数据包进行分片,使每一片的长度小于或等于MTU值。在分片过程中,除了对payload进行分片外,数据包的IP首部也需要进行相应的更改:
MSS
最大分段长度,TCP数据包每次能够传输的最大数据分段长度,在TCP协议的实际实现中,MSS往往用MTU-(IPHeader Length + TCP Header Length)来代替。在TCP通信建立连接时,取两端提供的MSS的最小值作为会话的MSS值。由于TCP分段有MSS值的限制,通常情况下TCP数据包经IP层封装后的长度不会大于MTU,因此一般情况下,TCP数据包不会进行IP分片。
早先TCP设计的目标是为了解决低速网络传输的不可靠性问题(拨号上网的年代),但随着互联网骨干传输速度的提升(光纤、千兆以太、万兆以太)以及用户端更可靠的访问机制的出现(ADSL等),相关的数据中心及客户端桌面环境上的TCP软件常常需要面临大量的计算需求。
当网络速度超过1Gb的时候,这些计算会耗费大量的CPU时间,有数据表明,即便使用千兆全双工网卡,TCP通信也将消耗CPU的80%的使用率(以2.4GHz奔腾4处理器为例),这样留给其他应用程序的时间就很少了,表现出来就是用户可能感觉到很慢。
小编注:当年的蠕虫病毒对CPU的影响与此近似。
为了解决性能问题,就产生了TOE技术(TCP offload engine),将TCP连接过程中的相关计算工作转移到专用硬件上(比如网卡),从而释放CPU资源。从2012年开始,这项技术开始在普通用户的网卡上应用。
随着技术的日趋成熟,目前越来越多的网卡设备开始支持offload特性,以便提升网络收发和处理的性能。本文所描述的offload特性,主要是指将原本在协议栈中进行的IP分片、TCP分段、重组、checksum校验等操作,转移到网卡硬件中进行,降低系统CPU的消耗,提高处理性能。
从名字来看很直观,就是把tcp分段的过程转移到网卡中进行。当网卡支持TSO机制时,可以直接把不超过滑动窗口大小的payload下传给协议栈,即使数据长度大于MSS,也不会在TCP层进行分段,同样也不会进行IP分片,而是直接传送给网卡驱动,由网卡驱动进行tcp分段操作,并执行checksum计算和包头、帧头的生成工作。例如,
在本地主机上(10.8.55.1)发送一个超长的HTTP请求,当TSO模式关闭时,10.8.55.1抓包如下
当TSO模式开启时,10.8.55.1抓包如下:
**UFO(udp-fragmentation-offload) **
是一种专门针对udp协议的特性,主要机制就是将IP分片的过程转移到网卡中进行,用户层可以发送任意大小的udp数据包(udp数据包总长度最大不超过64k),而不需要协议栈进行任何分片操作。目前貌似没找到有支持UFO机制的网卡,主要是应用在虚拟化设备上。
**GSO(generic-segmentation-offload) **
相对于TSO和UFO,GSO机制是针对所有协议设计的,更为通用。同时,与TSO、UFO不同的是,GSO主要依靠软件的方式实现,对于网卡硬件没有过多的要求。其基本思想就是把数据分片的操作尽可能的向底层推迟直到数据发送给网卡驱动之前,并先检查网卡是否支持TSO或UFO机制,如果支持就直接把数据发送给网卡,否则的话再进行分片后发送给网卡,以此来保证最少次数的协议栈处理,提高数据传输和处理的效率。
在网卡驱动层面上将接受到的多个TCP数据包聚合成一个大的数据包,然后上传给协议栈处理。这样可以减少协议栈处理的开销,提高系统接收TCP数据的能力和效率。
generic-receive-offload,基本思想和LRO类似,只是改善了LRO的一些缺点,比LRO更加通用。目前及后续的网卡都采用GRO机制,不再使用LRO机制。例如,
当本地主机(10.51.19.40)开启GRO模式时,从主机10.8.55.11向主机10.51.19.40发送一个超长请求。
10.8.55.11抓包如下:
10.51.19.40抓包如下:
**RSS(Receive Side Scaling)**
具备多个RSS队列的网卡,可以将不同的网络流分成不同的队列,再将这些队列分配到多个CPU核心上进行处理,从而将负荷分散,充分利用多核处理器的能力,提交数据接收的能力和效率。
Linux
在linux系统下,可以通过ethtool查看各模式的状态并进行设置:
**查看状态 **
1. ethtool –k 设备名
**设置开关状态 **
windows
在windows系统下,可以通过设备管理器中网卡设备的属性对网卡模式进行查看和调整。以Intel 82579LM和Intel I217-LM网卡为例
目前常用的抓包工具大部分都是从协议栈中(如数据链路层)捕获数据包,而网卡的offload特性会将数据包的分片、重组等工作转移到协议栈以下的硬件层面进行,因此在开启TSO、GRO等机制的情况下,我们使用tcpdump、wireshark等工具抓取到的数据包往往不能真实反应链路上实际的数据帧,给网络流量特征的分析造成不利影响。
在某些情况下,例如分片攻击等攻击方式,甚至可能会因为网卡设备的offload机制处理,而规避防火墙、IDS以及人工的检查。针对这些情况,可以选择关闭网卡offload的相关选项,或者在链路的其他节点进行抓包。