Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 45e15bb7 authored by Santiago Leon's avatar Santiago Leon Committed by Jeff Garzik
Browse files

ibmveth: fix bad UDP checksums



This patch fixes a ibmveth bug where bad UDP checksums are being transmitted
when checksum offloading is enabled.
The hypervisor does checksum offloading only on TCP packets, so ibmveth calls
skb_checksum_help() for any other protocol.  The bug happens because
the packet is being modified after the DMA map, so we would need a memory
barrier before making the hypervisor call.  Reordering the code so that the
DMA map happens after skb_checksum_help() has the additional advantage of
fixing a DMA map leak if skb_checksum_help() where to fail.

Signed-off-by: default avatarSantiago Leon <santil@us.ibm.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent c213f286
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -904,8 +904,6 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
	unsigned long data_dma_addr;

	desc.fields.flags_len = IBMVETH_BUF_VALID | skb->len;
	data_dma_addr = dma_map_single(&adapter->vdev->dev, skb->data,
				       skb->len, DMA_TO_DEVICE);

	if (skb->ip_summed == CHECKSUM_PARTIAL &&
	    ip_hdr(skb)->protocol != IPPROTO_TCP && skb_checksum_help(skb)) {
@@ -924,6 +922,8 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
		buf[1] = 0;
	}

	data_dma_addr = dma_map_single(&adapter->vdev->dev, skb->data,
				       skb->len, DMA_TO_DEVICE);
	if (dma_mapping_error(&adapter->vdev->dev, data_dma_addr)) {
		if (!firmware_has_feature(FW_FEATURE_CMO))
			ibmveth_error_printk("tx: unable to map xmit buffer\n");
@@ -932,6 +932,7 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
		desc.fields.address = adapter->bounce_buffer_dma;
		tx_map_failed++;
		used_bounce = 1;
		wmb();
	} else
		desc.fields.address = data_dma_addr;