diff options
Diffstat (limited to 'net/core/dev.c')
-rw-r--r-- | net/core/dev.c | 35 |
1 files changed, 13 insertions, 22 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 01993ad74e76..600bb23c4c2e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1939,22 +1939,6 @@ int netif_rx_ni(struct sk_buff *skb) | |||
1939 | 1939 | ||
1940 | EXPORT_SYMBOL(netif_rx_ni); | 1940 | EXPORT_SYMBOL(netif_rx_ni); |
1941 | 1941 | ||
1942 | static inline struct net_device *skb_bond(struct sk_buff *skb) | ||
1943 | { | ||
1944 | struct net_device *dev = skb->dev; | ||
1945 | |||
1946 | if (dev->master) { | ||
1947 | if (skb_bond_should_drop(skb)) { | ||
1948 | kfree_skb(skb); | ||
1949 | return NULL; | ||
1950 | } | ||
1951 | skb->dev = dev->master; | ||
1952 | } | ||
1953 | |||
1954 | return dev; | ||
1955 | } | ||
1956 | |||
1957 | |||
1958 | static void net_tx_action(struct softirq_action *h) | 1942 | static void net_tx_action(struct softirq_action *h) |
1959 | { | 1943 | { |
1960 | struct softnet_data *sd = &__get_cpu_var(softnet_data); | 1944 | struct softnet_data *sd = &__get_cpu_var(softnet_data); |
@@ -2181,6 +2165,7 @@ int netif_receive_skb(struct sk_buff *skb) | |||
2181 | { | 2165 | { |
2182 | struct packet_type *ptype, *pt_prev; | 2166 | struct packet_type *ptype, *pt_prev; |
2183 | struct net_device *orig_dev; | 2167 | struct net_device *orig_dev; |
2168 | struct net_device *null_or_orig; | ||
2184 | int ret = NET_RX_DROP; | 2169 | int ret = NET_RX_DROP; |
2185 | __be16 type; | 2170 | __be16 type; |
2186 | 2171 | ||
@@ -2194,10 +2179,14 @@ int netif_receive_skb(struct sk_buff *skb) | |||
2194 | if (!skb->iif) | 2179 | if (!skb->iif) |
2195 | skb->iif = skb->dev->ifindex; | 2180 | skb->iif = skb->dev->ifindex; |
2196 | 2181 | ||
2197 | orig_dev = skb_bond(skb); | 2182 | null_or_orig = NULL; |
2198 | 2183 | orig_dev = skb->dev; | |
2199 | if (!orig_dev) | 2184 | if (orig_dev->master) { |
2200 | return NET_RX_DROP; | 2185 | if (skb_bond_should_drop(skb)) |
2186 | null_or_orig = orig_dev; /* deliver only exact match */ | ||
2187 | else | ||
2188 | skb->dev = orig_dev->master; | ||
2189 | } | ||
2201 | 2190 | ||
2202 | __get_cpu_var(netdev_rx_stat).total++; | 2191 | __get_cpu_var(netdev_rx_stat).total++; |
2203 | 2192 | ||
@@ -2221,7 +2210,8 @@ int netif_receive_skb(struct sk_buff *skb) | |||
2221 | #endif | 2210 | #endif |
2222 | 2211 | ||
2223 | list_for_each_entry_rcu(ptype, &ptype_all, list) { | 2212 | list_for_each_entry_rcu(ptype, &ptype_all, list) { |
2224 | if (!ptype->dev || ptype->dev == skb->dev) { | 2213 | if (ptype->dev == null_or_orig || ptype->dev == skb->dev || |
2214 | ptype->dev == orig_dev) { | ||
2225 | if (pt_prev) | 2215 | if (pt_prev) |
2226 | ret = deliver_skb(skb, pt_prev, orig_dev); | 2216 | ret = deliver_skb(skb, pt_prev, orig_dev); |
2227 | pt_prev = ptype; | 2217 | pt_prev = ptype; |
@@ -2246,7 +2236,8 @@ ncls: | |||
2246 | list_for_each_entry_rcu(ptype, | 2236 | list_for_each_entry_rcu(ptype, |
2247 | &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) { | 2237 | &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) { |
2248 | if (ptype->type == type && | 2238 | if (ptype->type == type && |
2249 | (!ptype->dev || ptype->dev == skb->dev)) { | 2239 | (ptype->dev == null_or_orig || ptype->dev == skb->dev || |
2240 | ptype->dev == orig_dev)) { | ||
2250 | if (pt_prev) | 2241 | if (pt_prev) |
2251 | ret = deliver_skb(skb, pt_prev, orig_dev); | 2242 | ret = deliver_skb(skb, pt_prev, orig_dev); |
2252 | pt_prev = ptype; | 2243 | pt_prev = ptype; |