Commit 9a8d9492 authored by Andrew's avatar Andrew Committed by Jason Wang
Browse files

hw/net: Added CSO for IPv6



Added fix for checksum offload for IPv6 if a backend doesn't
have a virtual header.
This patch is a part of IPv6 fragmentation.

Signed-off-by: default avatarAndrew Melnychenko <andrew@daynix.com>
Signed-off-by: default avatarJason Wang <jasowang@redhat.com>
parent 65018100
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -468,8 +468,8 @@ static void net_tx_pkt_do_sw_csum(struct NetTxPkt *pkt)
    /* num of iovec without vhdr */
    uint32_t iov_len = pkt->payload_frags + NET_TX_PKT_PL_START_FRAG - 1;
    uint16_t csl;
    struct ip_header *iphdr;
    size_t csum_offset = pkt->virt_hdr.csum_start + pkt->virt_hdr.csum_offset;
    uint16_t l3_proto = eth_get_l3_proto(iov, 1, iov->iov_len);

    /* Put zero to checksum field */
    iov_from_buf(iov, iov_len, csum_offset, &csum, sizeof csum);
@@ -477,9 +477,18 @@ static void net_tx_pkt_do_sw_csum(struct NetTxPkt *pkt)
    /* Calculate L4 TCP/UDP checksum */
    csl = pkt->payload_len;

    csum_cntr = 0;
    cso = 0;
    /* add pseudo header to csum */
    iphdr = pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_base;
    csum_cntr = eth_calc_ip4_pseudo_hdr_csum(iphdr, csl, &cso);
    if (l3_proto == ETH_P_IP) {
        csum_cntr = eth_calc_ip4_pseudo_hdr_csum(
                pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_base,
                csl, &cso);
    } else if (l3_proto == ETH_P_IPV6) {
        csum_cntr = eth_calc_ip6_pseudo_hdr_csum(
                pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_base,
                csl, pkt->l4proto, &cso);
    }

    /* data checksum */
    csum_cntr +=