Skip to contentSkip to conversation

Patch "gro: Make GRO aware of lightweight tunnels." has been added to the 4.4-stable tree

PATCH [email protected] 1 participant 1 message Feb 29, 2016

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

gro: Make GRO aware of lightweight tunnels.

to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
gro-make-gro-aware-of-lightweight-tunnels.patch
and it can be found in the queue-4.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From foo@baz Mon Feb 29 14:33:50 PST 2016

From: Jesse Gross <[email protected]>
Date: Wed, 20 Jan 2016 17:59:49 -0800
Subject: gro: Make GRO aware of lightweight tunnels.

From: Jesse Gross <[email protected]>

[ Upstream commit ce87fc6ce3f9f4488546187e3757cf666d9d4a2a ]

GRO is currently not aware of tunnel metadata generated by lightweight tunnels and stored in the dst. This leads to two possible problems:
* Incorrectly merging two frames that have different metadata.
* Leaking of allocated metadata from merged frames.

This avoids those problems by comparing the tunnel information before merging, similar to how we handle other metadata (such as vlan tags), and releasing any state when we are done.

Fixes 2e15ea39 ("ip_gre: Add support to collect tunnel metadata.")
---
 include/net/dst_metadata.h |   18 ++++++++++++++++++
 net/core/dev.c             |    7 +++++--
 2 files changed, 23 insertions(+), 2 deletions(-)
include/net/dst_metadata.h +18 -0
@@ -44,6 +44,24 @@ static inline bool skb_valid_dst(const s
 	return dst && !(dst->flags & DST_METADATA);
 }
 
+static inline int skb_metadata_dst_cmp(const struct sk_buff *skb_a,
+				       const struct sk_buff *skb_b)
+{
+	const struct metadata_dst *a, *b;
+
+	if (!(skb_a->_skb_refdst | skb_b->_skb_refdst))
+		return 0;
+
+	a = (const struct metadata_dst *) skb_dst(skb_a);
+	b = (const struct metadata_dst *) skb_dst(skb_b);
+
+	if (!a != !b || a->u.tun_info.options_len != b->u.tun_info.options_len)
+		return 1;
+
+	return memcmp(&a->u.tun_info, &b->u.tun_info,
+		      sizeof(a->u.tun_info) + a->u.tun_info.options_len);
+}
+
 struct metadata_dst *metadata_dst_alloc(u8 optslen, gfp_t flags);
 struct metadata_dst __percpu *metadata_dst_alloc_percpu(u8 optslen, gfp_t flags);
 
net/core/dev.c +5 -2
@@ -4145,6 +4145,7 @@ static void gro_list_prepare(struct napi
 
 		diffs = (unsigned long)p->dev ^ (unsigned long)skb->dev;
 		diffs |= p->vlan_tci ^ skb->vlan_tci;
+		diffs |= skb_metadata_dst_cmp(p, skb);
 		if (maclen == ETH_HLEN)
 			diffs |= compare_ether_header(skb_mac_header(p),
 						      skb_mac_header(skb));
@@ -4342,10 +4343,12 @@ static gro_result_t napi_skb_finish(gro_
 		break;
 
 	case GRO_MERGED_FREE:
-		if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD)
+		if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD) {
+			skb_dst_drop(skb);
 			kmem_cache_free(skbuff_head_cache, skb);
-		else
+		} else {
 			__kfree_skb(skb);
+		}
 		break;
 
 	case GRO_HELD:

Patches currently in stable-queue which might be from [email protected] are

queue-4.4/tunnels-allow-ipv6-udp-checksums-to-be-correctly-controlled.patch queue-4.4/gro-make-gro-aware-of-lightweight-tunnels.patch queue-4.4/lwt-fix-rx-checksum-setting-for-lwt-devices-tunneling-over-ipv6.patch