diff options
-rw-r--r-- | drivers/net/macvlan.c | 8 | ||||
-rw-r--r-- | include/linux/if_macvlan.h | 3 | ||||
-rw-r--r-- | net/core/dev.c | 10 |
3 files changed, 11 insertions, 10 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 9a939d828b47..1b78c0057a8d 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
@@ -145,19 +145,15 @@ static void macvlan_broadcast(struct sk_buff *skb, | |||
145 | } | 145 | } |
146 | 146 | ||
147 | /* called under rcu_read_lock() from netif_receive_skb */ | 147 | /* called under rcu_read_lock() from netif_receive_skb */ |
148 | static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb) | 148 | static struct sk_buff *macvlan_handle_frame(struct macvlan_port *port, |
149 | struct sk_buff *skb) | ||
149 | { | 150 | { |
150 | const struct ethhdr *eth = eth_hdr(skb); | 151 | const struct ethhdr *eth = eth_hdr(skb); |
151 | const struct macvlan_port *port; | ||
152 | const struct macvlan_dev *vlan; | 152 | const struct macvlan_dev *vlan; |
153 | const struct macvlan_dev *src; | 153 | const struct macvlan_dev *src; |
154 | struct net_device *dev; | 154 | struct net_device *dev; |
155 | unsigned int len; | 155 | unsigned int len; |
156 | 156 | ||
157 | port = rcu_dereference(skb->dev->macvlan_port); | ||
158 | if (port == NULL) | ||
159 | return skb; | ||
160 | |||
161 | if (is_multicast_ether_addr(eth->h_dest)) { | 157 | if (is_multicast_ether_addr(eth->h_dest)) { |
162 | src = macvlan_hash_lookup(port, eth->h_source); | 158 | src = macvlan_hash_lookup(port, eth->h_source); |
163 | if (!src) | 159 | if (!src) |
diff --git a/include/linux/if_macvlan.h b/include/linux/if_macvlan.h index b78a712247da..9ea047aca795 100644 --- a/include/linux/if_macvlan.h +++ b/include/linux/if_macvlan.h | |||
@@ -85,6 +85,7 @@ extern netdev_tx_t macvlan_start_xmit(struct sk_buff *skb, | |||
85 | struct net_device *dev); | 85 | struct net_device *dev); |
86 | 86 | ||
87 | 87 | ||
88 | extern struct sk_buff *(*macvlan_handle_frame_hook)(struct sk_buff *); | 88 | extern struct sk_buff *(*macvlan_handle_frame_hook)(struct macvlan_port *, |
89 | struct sk_buff *); | ||
89 | 90 | ||
90 | #endif /* _LINUX_IF_MACVLAN_H */ | 91 | #endif /* _LINUX_IF_MACVLAN_H */ |
diff --git a/net/core/dev.c b/net/core/dev.c index 3daee30a7c82..5cbba0927a8e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2612,7 +2612,8 @@ static inline struct sk_buff *handle_bridge(struct sk_buff *skb, | |||
2612 | #endif | 2612 | #endif |
2613 | 2613 | ||
2614 | #if defined(CONFIG_MACVLAN) || defined(CONFIG_MACVLAN_MODULE) | 2614 | #if defined(CONFIG_MACVLAN) || defined(CONFIG_MACVLAN_MODULE) |
2615 | struct sk_buff *(*macvlan_handle_frame_hook)(struct sk_buff *skb) __read_mostly; | 2615 | struct sk_buff *(*macvlan_handle_frame_hook)(struct macvlan_port *p, |
2616 | struct sk_buff *skb) __read_mostly; | ||
2616 | EXPORT_SYMBOL_GPL(macvlan_handle_frame_hook); | 2617 | EXPORT_SYMBOL_GPL(macvlan_handle_frame_hook); |
2617 | 2618 | ||
2618 | static inline struct sk_buff *handle_macvlan(struct sk_buff *skb, | 2619 | static inline struct sk_buff *handle_macvlan(struct sk_buff *skb, |
@@ -2620,14 +2621,17 @@ static inline struct sk_buff *handle_macvlan(struct sk_buff *skb, | |||
2620 | int *ret, | 2621 | int *ret, |
2621 | struct net_device *orig_dev) | 2622 | struct net_device *orig_dev) |
2622 | { | 2623 | { |
2623 | if (skb->dev->macvlan_port == NULL) | 2624 | struct macvlan_port *port; |
2625 | |||
2626 | port = rcu_dereference(skb->dev->macvlan_port); | ||
2627 | if (!port) | ||
2624 | return skb; | 2628 | return skb; |
2625 | 2629 | ||
2626 | if (*pt_prev) { | 2630 | if (*pt_prev) { |
2627 | *ret = deliver_skb(skb, *pt_prev, orig_dev); | 2631 | *ret = deliver_skb(skb, *pt_prev, orig_dev); |
2628 | *pt_prev = NULL; | 2632 | *pt_prev = NULL; |
2629 | } | 2633 | } |
2630 | return macvlan_handle_frame_hook(skb); | 2634 | return macvlan_handle_frame_hook(port, skb); |
2631 | } | 2635 | } |
2632 | #else | 2636 | #else |
2633 | #define handle_macvlan(skb, pt_prev, ret, orig_dev) (skb) | 2637 | #define handle_macvlan(skb, pt_prev, ret, orig_dev) (skb) |