diff options
Diffstat (limited to 'net/core/dev.c')
| -rw-r--r-- | net/core/dev.c | 16 | 
1 files changed, 16 insertions, 0 deletions
| diff --git a/net/core/dev.c b/net/core/dev.c index c253c2aafe97..64b21f0a2048 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -6008,6 +6008,19 @@ static void gro_list_prepare(const struct list_head *head,  			diffs = memcmp(skb_mac_header(p),  				       skb_mac_header(skb),  				       maclen); + +		diffs |= skb_get_nfct(p) ^ skb_get_nfct(skb); +#if IS_ENABLED(CONFIG_SKB_EXTENSIONS) && IS_ENABLED(CONFIG_NET_TC_SKB_EXT) +		if (!diffs) { +			struct tc_skb_ext *skb_ext = skb_ext_find(skb, TC_SKB_EXT); +			struct tc_skb_ext *p_ext = skb_ext_find(p, TC_SKB_EXT); + +			diffs |= (!!p_ext) ^ (!!skb_ext); +			if (!diffs && unlikely(skb_ext)) +				diffs |= p_ext->chain ^ skb_ext->chain; +		} +#endif +  		NAPI_GRO_CB(p)->same_flow = !diffs;  	}  } @@ -6221,6 +6234,8 @@ static gro_result_t napi_skb_finish(struct napi_struct *napi,  	case GRO_MERGED_FREE:  		if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD)  			napi_skb_free_stolen_head(skb); +		else if (skb->fclone != SKB_FCLONE_UNAVAILABLE) +			__kfree_skb(skb);  		else  			__kfree_skb_defer(skb);  		break; @@ -6270,6 +6285,7 @@ static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb)  	skb_shinfo(skb)->gso_type = 0;  	skb->truesize = SKB_TRUESIZE(skb_end_offset(skb));  	skb_ext_reset(skb); +	nf_reset_ct(skb);  	napi->skb = skb;  } |