我在C语言中使用原始套接字编程,试图将IP标头校验和计算卸载到NIC。我已经检查了NIC上是否启用了校验和卸载。
$ ethtool -k enp1s0d1
Features for enp1s0d1:
rx-checksumming: on
tx-checksumming: on
tx-checksum-ipv4: on
tx-checksum-ip-generic: off [fixed]
tx-checksum-ipv6: on
tx-checksum-fcoe-crc: off [fixed]
tx-checksum-sctp: off [fixed]
在发送程序中,我已将IP标头校验和设置为0,即:
struct iphdr *iph;
iph->check = htons(0);
但是,接收方未接收到任何数据包。如果我使用以下代码手动设置IP标头校验和,则接收方可以接收数据包:
unsigned short checksum(unsigned short* buff, int _16bitword)
{
unsigned long sum;
for(sum=0;_16bitword>0;_16bitword--)
sum+=htons(*(buff)++);
do
{
sum = ((sum >> 16) + (sum & 0xFFFF));
}
while(sum & 0xFFFF0000);
return (~sum);
}
我想知道我做错了什么吗?我观察到其中一个内核文档(https://www.kernel.org/doc/Documentation/networking/checksum-offloads.txt)表示
不卸载IP头校验和;总是通过软件完成的。
那是原因吗?