We have an application running that requires tcp checksum to be offloaded.
The application we are using sends and receieves using packet socket.
sd = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
We tried tx checksum offloading which worked. Druring tx we did following things.
one = 1;
setsockopt(sd, SOL_PACKET, PACKET_VNET_HDR, &one, sizeof(one));
iov.iov_base = ether_frame;
iov.iov_len = VIRTIO_NET_HDR_LEN+ ETH_HDRLEN + IP4_HDRLEN + TCP_HDRLEN + payloadlen * sizeof (uint8_t);
msg.msg_name = &device;
msg.msg_namelen = sizeof(device);
msg.msg_control = 0;
msg.msg_controllen = 0;
msg.msg_flags = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
sendmsg (sd, &msg, 0);
In packet capture taken in recieving interface shows correct checksum in TCP checksum field.
But, when we tried to offload it in RX side, we are seeing that the checksum is not offloaded.
In RX side we did following things.
one = 1;
setsockopt(sd, SOL_PACKET, PACKET_VNET_HDR, &one, sizeof(one));
iov.iov_base = ether_frame;
iov.iov_len = VIRTIO_NET_HDR_LEN+DEV_IP_MAXPACKET;
msg.msg_name = &device;
msg.msg_namelen = sizeof(device);
msg.msg_control = 0;
msg.msg_controllen = 0;
msg.msg_flags = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
recvmsg (sd, &msg, 0);
memcpy (&vnet_hdr, ether_frame, sizeof(struct virtio_net_hdr));
Here vnet_hdr.flags is zero (niether VIRTIO_NET_HDR_F_NEEDS_CSUM nor VIRTIO_NET_HDR_F_DATA_VALID).
As per our understanding the flag should be set to VIRTIO_NET_HDR_F_DATA_VALID if checksum was correctly offloaded.
Are we missing anything?
Thanks,
Suman
Features (Configurations) enabled on interfaces -
Host (hyperviser) - we used vmnic1 for TX and vmnic2 for RX
-----------------------------------------------------------
~ # ethtool -k vmnic1
Offload parameters for vmnic1:
Cannot get device udp large send offload settings: Function not implemented
Cannot get device generic segmentation offload settings: Function not implemented
rx-checksumming: on
tx-checksumming: on
scatter-gather: on
tcp segmentation offload: on
udp fragmentation offload: off
generic segmentation offload: off
~ # ethtool -k vmnic2
Offload parameters for vmnic2:
Cannot get device udp large send offload settings: Function not implemented
Cannot get device generic segmentation offload settings: Function not implemented
rx-checksumming: on
tx-checksumming: on
scatter-gather: on
tcp segmentation offload: off
udp fragmentation offload: off
generic segmentation offload: off
Guest (CentOS) - we used eth8 for TX and eth9 for RX
----------------------------------------------------
Features for eth8:
rx-checksumming: on
tx-checksumming: on
tx-checksum-ipv4: 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: on
udp-fragmentation-offload: off [fixed]
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: on
Features for eth9:
rx-checksumming: on
tx-checksumming: on
tx-checksum-ipv4: 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: on
udp-fragmentation-offload: off [fixed]
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: on