Revert "net: remove skb_orphan_try()"

This reverts commit 73a3346556281fd56f39f0a9475249e5039d8807.

The change in question doesn't seem to apply to us, but conflicts with an
attempted cherry-pick of 6e3e939f3, so let's just take it out.

Change-Id: If48a800e4428a7687bea1227b4e9fcc576141f35
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 4b42eb7..70fd1e2 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -213,8 +213,11 @@
 	/* device driver is going to provide hardware time stamp */
 	SKBTX_IN_PROGRESS = 1 << 2,
 
+	/* ensure the originating sk reference is available on driver level */
+	SKBTX_DRV_NEEDS_SK_REF = 1 << 3,
+
 	/* device driver supports TX zero-copy buffers */
-	SKBTX_DEV_ZEROCOPY = 1 << 3,
+	SKBTX_DEV_ZEROCOPY = 1 << 4,
 };
 
 /*
diff --git a/net/can/raw.c b/net/can/raw.c
index 46cca3a..cde1b4a 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -681,6 +681,9 @@
 	if (err < 0)
 		goto free_skb;
 
+	/* to be able to check the received tx sock reference in raw_rcv() */
+	skb_shinfo(skb)->tx_flags |= SKBTX_DRV_NEEDS_SK_REF;
+
 	skb->dev = dev;
 	skb->sk  = sk;
 
diff --git a/net/core/dev.c b/net/core/dev.c
index 35ac2f6..31ca1a6 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2079,6 +2079,25 @@
 	return 0;
 }
 
+/*
+ * Try to orphan skb early, right before transmission by the device.
+ * We cannot orphan skb if tx timestamp is requested or the sk-reference
+ * is needed on driver level for other reasons, e.g. see net/can/raw.c
+ */
+static inline void skb_orphan_try(struct sk_buff *skb)
+{
+	struct sock *sk = skb->sk;
+
+	if (sk && !skb_shinfo(skb)->tx_flags) {
+		/* skb_tx_hash() wont be able to get sk.
+		 * We copy sk_hash into skb->rxhash
+		 */
+		if (!skb->rxhash)
+			skb->rxhash = sk->sk_hash;
+		skb_orphan(skb);
+	}
+}
+
 static bool can_checksum_protocol(unsigned long features, __be16 protocol)
 {
 	return ((features & NETIF_F_GEN_CSUM) ||
@@ -2163,6 +2182,8 @@
 		if (!list_empty(&ptype_all))
 			dev_queue_xmit_nit(skb, dev);
 
+		skb_orphan_try(skb);
+
 		features = netif_skb_features(skb);
 
 		if (vlan_tx_tag_present(skb) &&
@@ -2272,7 +2293,7 @@
 	if (skb->sk && skb->sk->sk_hash)
 		hash = skb->sk->sk_hash;
 	else
-		hash = (__force u16) skb->protocol;
+		hash = (__force u16) skb->protocol ^ skb->rxhash;
 	hash = jhash_1word(hash, hashrnd);
 
 	return (u16) (((u64) hash * qcount) >> 32) + qoffset;
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index cf98d62..274d150 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -380,6 +380,7 @@
 			skb_trim(skb, skb->dev->mtu);
 	}
 	skb->protocol = ETH_P_AF_IUCV;
+	skb_shinfo(skb)->tx_flags |= SKBTX_DRV_NEEDS_SK_REF;
 	nskb = skb_clone(skb, GFP_ATOMIC);
 	if (!nskb)
 		return -ENOMEM;