diff options
Diffstat (limited to 'net/core/dev.c')
| -rw-r--r-- | net/core/dev.c | 16 | 
1 files changed, 9 insertions, 7 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 83988362805..89e33a5d4d9 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2134,7 +2134,8 @@ static bool can_checksum_protocol(netdev_features_t features, __be16 protocol)  static netdev_features_t harmonize_features(struct sk_buff *skb,  	__be16 protocol, netdev_features_t features)  { -	if (!can_checksum_protocol(features, protocol)) { +	if (skb->ip_summed != CHECKSUM_NONE && +	    !can_checksum_protocol(features, protocol)) {  		features &= ~NETIF_F_ALL_CSUM;  		features &= ~NETIF_F_SG;  	} else if (illegal_highdma(skb->dev, skb)) { @@ -2647,15 +2648,16 @@ void __skb_get_rxhash(struct sk_buff *skb)  	if (!skb_flow_dissect(skb, &keys))  		return; -	if (keys.ports) { -		if ((__force u16)keys.port16[1] < (__force u16)keys.port16[0]) -			swap(keys.port16[0], keys.port16[1]); +	if (keys.ports)  		skb->l4_rxhash = 1; -	}  	/* get a consistent hash (same value on both flow directions) */ -	if ((__force u32)keys.dst < (__force u32)keys.src) +	if (((__force u32)keys.dst < (__force u32)keys.src) || +	    (((__force u32)keys.dst == (__force u32)keys.src) && +	     ((__force u16)keys.port16[1] < (__force u16)keys.port16[0]))) {  		swap(keys.dst, keys.src); +		swap(keys.port16[0], keys.port16[1]); +	}  	hash = jhash_3words((__force u32)keys.dst,  			    (__force u32)keys.src, @@ -3321,7 +3323,7 @@ ncls:  	if (pt_prev) {  		if (unlikely(skb_orphan_frags(skb, GFP_ATOMIC))) -			ret = -ENOMEM; +			goto drop;  		else  			ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);  	} else {  |