diff options
Diffstat (limited to 'net/core/dev.c')
| -rw-r--r-- | net/core/dev.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index bcc490cc9452..f769098774b7 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -80,6 +80,7 @@ | |||
| 80 | #include <linux/types.h> | 80 | #include <linux/types.h> |
| 81 | #include <linux/kernel.h> | 81 | #include <linux/kernel.h> |
| 82 | #include <linux/hash.h> | 82 | #include <linux/hash.h> |
| 83 | #include <linux/slab.h> | ||
| 83 | #include <linux/sched.h> | 84 | #include <linux/sched.h> |
| 84 | #include <linux/mutex.h> | 85 | #include <linux/mutex.h> |
| 85 | #include <linux/string.h> | 86 | #include <linux/string.h> |
| @@ -1988,8 +1989,12 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev, | |||
| 1988 | if (dev->real_num_tx_queues > 1) | 1989 | if (dev->real_num_tx_queues > 1) |
| 1989 | queue_index = skb_tx_hash(dev, skb); | 1990 | queue_index = skb_tx_hash(dev, skb); |
| 1990 | 1991 | ||
| 1991 | if (sk && sk->sk_dst_cache) | 1992 | if (sk) { |
| 1992 | sk_tx_queue_set(sk, queue_index); | 1993 | struct dst_entry *dst = rcu_dereference_bh(sk->sk_dst_cache); |
| 1994 | |||
| 1995 | if (dst && skb_dst(skb) == dst) | ||
| 1996 | sk_tx_queue_set(sk, queue_index); | ||
| 1997 | } | ||
| 1993 | } | 1998 | } |
| 1994 | } | 1999 | } |
| 1995 | 2000 | ||
| @@ -2483,6 +2488,7 @@ int netif_receive_skb(struct sk_buff *skb) | |||
| 2483 | { | 2488 | { |
| 2484 | struct packet_type *ptype, *pt_prev; | 2489 | struct packet_type *ptype, *pt_prev; |
| 2485 | struct net_device *orig_dev; | 2490 | struct net_device *orig_dev; |
| 2491 | struct net_device *master; | ||
| 2486 | struct net_device *null_or_orig; | 2492 | struct net_device *null_or_orig; |
| 2487 | struct net_device *null_or_bond; | 2493 | struct net_device *null_or_bond; |
| 2488 | int ret = NET_RX_DROP; | 2494 | int ret = NET_RX_DROP; |
| @@ -2503,11 +2509,12 @@ int netif_receive_skb(struct sk_buff *skb) | |||
| 2503 | 2509 | ||
| 2504 | null_or_orig = NULL; | 2510 | null_or_orig = NULL; |
| 2505 | orig_dev = skb->dev; | 2511 | orig_dev = skb->dev; |
| 2506 | if (orig_dev->master) { | 2512 | master = ACCESS_ONCE(orig_dev->master); |
| 2507 | if (skb_bond_should_drop(skb)) | 2513 | if (master) { |
| 2514 | if (skb_bond_should_drop(skb, master)) | ||
| 2508 | null_or_orig = orig_dev; /* deliver only exact match */ | 2515 | null_or_orig = orig_dev; /* deliver only exact match */ |
| 2509 | else | 2516 | else |
| 2510 | skb->dev = orig_dev->master; | 2517 | skb->dev = master; |
| 2511 | } | 2518 | } |
| 2512 | 2519 | ||
| 2513 | __get_cpu_var(netdev_rx_stat).total++; | 2520 | __get_cpu_var(netdev_rx_stat).total++; |
