2015-11-04 18:54, Jijiang Liu:
> +       /* if vhost TX checksum offload is required */
> +       if (m->ol_flags & PKT_TX_IP_CKSUM) {
> +               hdr->csum_start = m->l2_len;
> +               hdr->csum_offset = offsetof(struct ipv4_hdr, hdr_checksum);
> +       } else if (m->ol_flags & PKT_TX_L4_MASK) {
> +               hdr->csum_start = m->l2_len + m->l3_len;
> +               switch (m->ol_flags & PKT_TX_L4_MASK) {
> +               case PKT_TX_TCP_CKSUM:
> +                       hdr->csum_offset = offsetof(struct tcp_hdr, cksum);
> +                       break;
> +               case PKT_TX_UDP_CKSUM:
> +                       hdr->csum_offset = offsetof(struct udp_hdr,
> +                                                       dgram_cksum);
> +                       break;
> +               case PKT_TX_SCTP_CKSUM:
> +                       hdr->csum_offset = offsetof(struct sctp_hdr, cksum);
> +                       break;
> +               default:
> +                       break;
> +               }

The header checksum to offload is deduced from csum_offset.
Your vhost implementation do some parsing to deduce it:

> +     parse_ethernet(m, &l4_proto, &l4_hdr);
> +     if (hdr->flags == VIRTIO_NET_HDR_F_NEEDS_CSUM) {
> +             if ((hdr->csum_start == m->l2_len) &&
> +                     (hdr->csum_offset == offsetof(struct ipv4_hdr,
> +                                             hdr_checksum)))
> +                     m->ol_flags |= PKT_TX_IP_CKSUM;
> +             else if (hdr->csum_start == (m->l2_len + m->l3_len)) {
> +                     switch (hdr->csum_offset) {
> +                     case (offsetof(struct tcp_hdr, cksum)):
> +                             if (l4_proto == IPPROTO_TCP)
> +                                     m->ol_flags |= PKT_TX_TCP_CKSUM;
> +                             break;
> +                     case (offsetof(struct udp_hdr, dgram_cksum)):
> +                             if (l4_proto == IPPROTO_UDP)
> +                                     m->ol_flags |= PKT_TX_UDP_CKSUM;
> +                             break;
> +                     case (offsetof(struct sctp_hdr, cksum)):
> +                             if (l4_proto == IPPROTO_SCTP)
> +                                     m->ol_flags |= PKT_TX_SCTP_CKSUM;
> +                             break;
> +                     default:
> +                             break;
> +                     }
> +             }

The kernel doesn't work this way.
Please could you check that your virtio implementation works with a
vanilla Linux with or without vhost?
Thanks

Reply via email to