diff options
Diffstat (limited to 'net/core/dev.c')
| -rw-r--r-- | net/core/dev.c | 21 | 
1 files changed, 14 insertions, 7 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 723a34710ad..1f466e82ac3 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1488,6 +1488,7 @@ static inline void net_timestamp_check(struct sk_buff *skb)  int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)  {  	skb_orphan(skb); +	nf_reset(skb);  	if (!(dev->flags & IFF_UP) ||  	    (skb->len > (dev->mtu + dev->hard_header_len))) { @@ -1911,8 +1912,16 @@ static int dev_gso_segment(struct sk_buff *skb)   */  static inline void skb_orphan_try(struct sk_buff *skb)  { -	if (!skb_tx(skb)->flags) +	struct sock *sk = skb->sk; + +	if (sk && !skb_tx(skb)->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); +	}  }  int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, @@ -1998,8 +2007,7 @@ u16 skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb)  	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 * dev->real_num_tx_queues) >> 32); @@ -2022,12 +2030,11 @@ static inline u16 dev_cap_txqueue(struct net_device *dev, u16 queue_index)  static struct netdev_queue *dev_pick_tx(struct net_device *dev,  					struct sk_buff *skb)  { -	u16 queue_index; +	int queue_index;  	struct sock *sk = skb->sk; -	if (sk_tx_queue_recorded(sk)) { -		queue_index = sk_tx_queue_get(sk); -	} else { +	queue_index = sk_tx_queue_get(sk); +	if (queue_index < 0) {  		const struct net_device_ops *ops = dev->netdev_ops;  		if (ops->ndo_select_queue) {  |