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

Commit f7d70f74 authored by David L Stevens's avatar David L Stevens Committed by David S. Miller
Browse files

sunvnet: don't change gso data on clones



This patch unclones an skb for the case where the sunvnet driver needs to
change the segmentation size so that it doesn't interfere with TCP SACK's
use of them.

Signed-off-by: default avatarDavid L Stevens <david.stevens@oracle.com>
Acked-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1d6c4cca
Loading
Loading
Loading
Loading
+10 −13
Original line number Diff line number Diff line
@@ -1192,23 +1192,16 @@ static int vnet_handle_offloads(struct vnet_port *port, struct sk_buff *skb)
	skb_pull(skb, maclen);

	if (port->tso && gso_size < datalen) {
		if (skb_unclone(skb, GFP_ATOMIC))
			goto out_dropped;

		/* segment to TSO size */
		skb_shinfo(skb)->gso_size = datalen;
		skb_shinfo(skb)->gso_segs = gso_segs;

		segs = skb_gso_segment(skb, dev->features & ~NETIF_F_TSO);

		/* restore gso_size & gso_segs */
		skb_shinfo(skb)->gso_size = gso_size;
		skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len - hlen,
							 gso_size);
	} else
		segs = skb_gso_segment(skb, dev->features & ~NETIF_F_TSO);
	if (IS_ERR(segs)) {
		dev->stats.tx_dropped++;
		dev_kfree_skb_any(skb);
		return NETDEV_TX_OK;
	}
	segs = skb_gso_segment(skb, dev->features & ~NETIF_F_TSO);
	if (IS_ERR(segs))
		goto out_dropped;

	skb_push(skb, maclen);
	skb_reset_mac_header(skb);
@@ -1246,6 +1239,10 @@ static int vnet_handle_offloads(struct vnet_port *port, struct sk_buff *skb)
	if (!(status & NETDEV_TX_MASK))
		dev_kfree_skb_any(skb);
	return status;
out_dropped:
	dev->stats.tx_dropped++;
	dev_kfree_skb_any(skb);
	return NETDEV_TX_OK;
}

static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)