免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6989 | 回复: 7
打印 上一主题 下一主题

[LINUX][DRIVER]网卡(千兆网卡)是如何检验checksum的? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-06-03 18:32 |只看该作者 |倒序浏览
这个话题是提问linux中支持硬件检验和的网卡是如何检验checksum的?

TCP/UDP协议收到数据包后, 会检查checksum。UDP层检验checksum时,
检查的内容包含一个伪头,UDP头部,以及负载。格式如下:

---------------------------------------------------+
bits         0 – 7         8 – 15   16 – 23     24 – 31    |
0                    Source address                   |  
32                    Destination address               |
64         Zeros |        Protocol |              UDP length          |
---------------------------------------------------+
96         Source Port         |     Destination Port       |
128         Length         |          Checksum          |
---------------------------------------------------+
                                                     |
                   Data                            |
                                                   |
---------------------------------------------------+
伪头:就是前面8个字节
udp头:就是中间的8个字节。
负载: 就是DATA部分。注意data的长度不一定等于udp头部的length值,而等于所有负载的长度,即等于skb中len。


当一个网卡收到数据包时,是如何进行进行checksum的?下面是我的猜测:
收到数据包后,识别开IP头,UDP头,然后仅仅是对UDP头部length所指向的数据长度,结合udp头部的checksum进行校验。
如果checksum正确,就设置skb中的ip_summed为CHECKSUM_UNNECESSARY,就是告诉UDP层不要再进行检验校验和了。

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
2 [报告]
发表于 2010-06-04 09:30 |只看该作者
可以找一下内核中支持硬件计算校验和的驱动代码看一下

论坛徽章:
0
3 [报告]
发表于 2010-06-04 10:24 |只看该作者
"支持硬件检验和的网卡是如何检验checksum的?"

如果是E1000, 在硬件中直接做掉了,在RCV DESCRIPTOR中有一个BIT,表示CHECKSUM是否通过。再往OS传就不清楚鸟。

可以直接看 PCI/PCI-X Family of Gigabit Ethernet
Controllers Software Developer’s
Manual

论坛徽章:
0
4 [报告]
发表于 2010-06-05 23:04 |只看该作者
你好,谢谢的回复。
我只看懂了下面的代码,还没有找到网卡驱动是如何计算checksum的。


e1000e的网卡是支持硬件检验checksum。那这部分工作应该是硬件来完成的,而不是驱动来完成。
驱动中有计算 checksum的代码吗?

下面的代码是检查完checksum之后,用来设置skb->ip_summed值的。
  1. drivers/net/e1000e/netdev.c
  2. /**
  3. * e1000_rx_checksum - Receive Checksum Offload for 82543
  4. * @adapter:     board private structure
  5. * @status_err:  receive descriptor status and error fields
  6. * @csum:        receive descriptor csum field
  7. * @sk_buff:     socket buffer with received data
  8. **/
  9. static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
  10.                               u32 csum, struct sk_buff *skb)
  11. {
  12.         u16 status = (u16)status_err;
  13.         u8 errors = (u8)(status_err >> 24);
  14.         skb->ip_summed = CHECKSUM_NONE;

  15.         /* Ignore Checksum bit is set */
  16.         if (status & E1000_RXD_STAT_IXSM)
  17.                 return;
  18.         /* TCP/UDP checksum error bit is set */
  19.         if (errors & E1000_RXD_ERR_TCPE) {  <===checksun错误
  20.                 /* let the stack verify checksum errors */
  21.                 adapter->hw_csum_err++;
  22.                 return;
  23.         }

  24.         /* TCP/UDP Checksum has not been calculated */
  25.         if (!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)))
  26.                 return;

  27.         /* It must be a TCP or UDP packet with a valid checksum */
  28.         if (status & E1000_RXD_STAT_TCPCS) {
  29.                 /* TCP checksum is good */
  30.                 skb->ip_summed = CHECKSUM_UNNECESSARY; //这里检验和计算正确。也就是说网卡已经检查了L4层的伪头,L4层头部,L4层负载以及L4层中所包含的checksum字段。这就告诉L4层不要再check checksum了。
  31.         } else {
  32.                 /*
  33.                  * IP fragment with UDP payload
  34.                  * Hardware complements the payload checksum, so we undo it
  35.                  * and then put the value in host order for further stack use.
  36.                  */
  37.                 __sum16 sum = (__force __sum16)htons(csum);
  38.                 skb->csum = csum_unfold(~sum);
  39.                 skb->ip_summed = CHECKSUM_COMPLETE;
  40.         }
  41.         adapter->hw_csum_good++;
  42. }
复制代码
可以找一下内核中支持硬件计算校验和的驱动代码看一下
Godbach 发表于 2010-06-04 09:30

论坛徽章:
0
5 [报告]
发表于 2010-06-05 23:10 |只看该作者
硬件直接做的是CRC检验吧。CRC和checksum校验是不同的。
硬件检查完L4层的checksum是OK的,则L4层就可以不再检查checksum了。

"支持硬件检验和的网卡是如何检验checksum的?"

如果是E1000, 在硬件中直接做掉了,在RCV DESCRIPTOR中有 ...
accessory 发表于 2010-06-04 10:24

论坛徽章:
0
6 [报告]
发表于 2010-06-05 23:27 |只看该作者
有点不清楚LZ你想问啥。下面是E1000硬件手册里关于CHECKSUM部分

2.7.1 Checksum Offloading
The Ethernet controller provides the ability to offload the IP, TCP, and UDP checksum requirements
from the software device driver. For common frame types, the hardware automatically
calculates, inserts, and checks the appropriate checksum values normally handled by software.
For transmits, every Ethernet packet might have two checksums calculated and inserted by the
Ethernet controller. Typically, these would be the IP checksum, and either the TCP or UDP
checksum. The software device driver specifies which portions of the packet are included in the
checksum calculations, and where the calculated values are inserted via descriptors (refer to
Section 3.3.5 for details).
For receives, the hardware recognizes the packet type and performs the checksum calculations and
error checking automatically. Checksum and error information is provided to software through the
receive descriptors (refer to Section 3.2.9 for details).


ref:
http://download.intel.com/design ... s/8254x_GBe_SDM.pdf

论坛徽章:
0
7 [报告]
发表于 2010-06-07 22:30 |只看该作者
你好, 非常谢谢你的文档。
我重新换个角度问个问题吧。

网卡自动检查TCP/UDP层的checksum,这个是硬件来实现的。
另外, 协议也是有能力来检查TCP/UDP层的checksum, 这个称为软件方式。
对于同一个数据包,硬件和软件检查的结果,应该是相同的。

对于UDP协议、检查checksum的方式是:将伪头, UDP头,以及UDP头部中length所指向的负荷, 二进制数取反求和, 如果结果为1,则说明UDP层的checksum是正确的。
但是现在我发现如果skb->len比UDP的length的值大时(比如UDP的负荷总长度是20字节,而UDP头部的length是16. UDP头部的checksum包含了20字节的负荷),硬件和软件所计算出来的checksun是不一致的。

所以, 我想问的是硬件检查checksunm时, 究竟是只验证了UDP头部中length所指向的负荷还是整个负载?


有点不清楚LZ你想问啥。下面是E1000硬件手册里关于CHECKSUM部分

2.7.1 Checksum Offloading
The Ethern ...
accessory 发表于 2010-06-05 23:27

论坛徽章:
0
8 [报告]
发表于 2010-06-07 23:43 |只看该作者
具体细节就不清楚了。

不过有几个问题,也许有帮助:

“如果skb->len比UDP的length的值大时”, 这个是正常情况么?如果是,在相关的RFC(假设有RFC的情况)中定义了标准的行为么?如果有,那么应该都是按照标准做的。如果没有,那就看每个硬件具体的实现了,RTFM.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP