• E
    e1000: Separate TSO and non-TSO contexts, fixing UDP TX corruption · d62644b4
    Ed Swierk via Qemu-devel 提交于
    The device is supposed to maintain two distinct contexts for transmit
    offloads: one has parameters for both segmentation and checksum
    offload, the other only for checksum offload. The guest driver can
    send two context descriptors, one for each context (the TSE flag
    specifies which). Then the guest can refer to one or the other context
    in subsequent transmit data descriptors, depending on what offloads it
    wants applied to each packet.
    
    Currently the e1000 device stores just one context, and misinterprets
    the TSE flags in the context and data descriptors. This is often okay:
    Linux happens to send a fresh context descriptor before every data
    descriptor, so forgetting the other context doesn't matter. Windows
    does rely on separate contexts for TSO vs. non-TSO packets, but for
    mostly-TCP traffic the two contexts have identical TCP-specific
    offload parameters so confusing them doesn't matter.
    
    One case where this confusion matters is when a Windows guest sets up
    a TSO context for TCP and a non-TSO context for UDP, and then
    transmits both TCP and UDP traffic in parallel. The e1000 device
    sometimes ends up using TCP-specific parameters while doing checksum
    offload on a UDP datagram: it writes the checksum to offset 16 (the
    correct location for a TCP checksum), stomping on two bytes of UDP
    data, and leaving the wrong value in the actual UDP checksum field at
    offset 6. (Even worse, the host network stack may then recompute the
    UDP checksum, "correcting" it to match the corrupt data before sending
    it out a physical interface.)
    
    Correct this by tracking the TSO context independently of the non-TSO
    context, and selecting the appropriate context based on the TSE flag
    in each transmit data descriptor.
    Signed-off-by: NEd Swierk <eswierk@skyportsystems.com>
    Signed-off-by: NJason Wang <jasowang@redhat.com>
    d62644b4
e1000.c 57.2 KB