aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/core/dev.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 4a09833331f1..dab97c7cf275 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2165,6 +2165,7 @@ int netif_receive_skb(struct sk_buff *skb)
2165{ 2165{
2166 struct packet_type *ptype, *pt_prev; 2166 struct packet_type *ptype, *pt_prev;
2167 struct net_device *orig_dev; 2167 struct net_device *orig_dev;
2168 struct net_device *null_or_orig;
2168 int ret = NET_RX_DROP; 2169 int ret = NET_RX_DROP;
2169 __be16 type; 2170 __be16 type;
2170 2171
@@ -2178,13 +2179,13 @@ int netif_receive_skb(struct sk_buff *skb)
2178 if (!skb->iif) 2179 if (!skb->iif)
2179 skb->iif = skb->dev->ifindex; 2180 skb->iif = skb->dev->ifindex;
2180 2181
2182 null_or_orig = NULL;
2181 orig_dev = skb->dev; 2183 orig_dev = skb->dev;
2182 if (orig_dev->master) { 2184 if (orig_dev->master) {
2183 if (skb_bond_should_drop(skb)) { 2185 if (skb_bond_should_drop(skb))
2184 kfree_skb(skb); 2186 null_or_orig = orig_dev; /* deliver only exact match */
2185 return NET_RX_DROP; 2187 else
2186 } 2188 skb->dev = orig_dev->master;
2187 skb->dev = orig_dev->master;
2188 } 2189 }
2189 2190
2190 __get_cpu_var(netdev_rx_stat).total++; 2191 __get_cpu_var(netdev_rx_stat).total++;
@@ -2209,7 +2210,7 @@ int netif_receive_skb(struct sk_buff *skb)
2209#endif 2210#endif
2210 2211
2211 list_for_each_entry_rcu(ptype, &ptype_all, list) { 2212 list_for_each_entry_rcu(ptype, &ptype_all, list) {
2212 if (!ptype->dev || ptype->dev == skb->dev) { 2213 if (ptype->dev == null_or_orig || ptype->dev == skb->dev) {
2213 if (pt_prev) 2214 if (pt_prev)
2214 ret = deliver_skb(skb, pt_prev, orig_dev); 2215 ret = deliver_skb(skb, pt_prev, orig_dev);
2215 pt_prev = ptype; 2216 pt_prev = ptype;
@@ -2234,7 +2235,7 @@ ncls:
2234 list_for_each_entry_rcu(ptype, 2235 list_for_each_entry_rcu(ptype,
2235 &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) { 2236 &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) {
2236 if (ptype->type == type && 2237 if (ptype->type == type &&
2237 (!ptype->dev || ptype->dev == skb->dev)) { 2238 (ptype->dev == null_or_orig || ptype->dev == skb->dev)) {
2238 if (pt_prev) 2239 if (pt_prev)
2239 ret = deliver_skb(skb, pt_prev, orig_dev); 2240 ret = deliver_skb(skb, pt_prev, orig_dev);
2240 pt_prev = ptype; 2241 pt_prev = ptype;