aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/macvlan.c8
-rw-r--r--include/linux/if_macvlan.h3
-rw-r--r--net/core/dev.c10
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 */
148static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb) 148static 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
88extern struct sk_buff *(*macvlan_handle_frame_hook)(struct sk_buff *); 88extern 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)
2615struct sk_buff *(*macvlan_handle_frame_hook)(struct sk_buff *skb) __read_mostly; 2615struct sk_buff *(*macvlan_handle_frame_hook)(struct macvlan_port *p,
2616 struct sk_buff *skb) __read_mostly;
2616EXPORT_SYMBOL_GPL(macvlan_handle_frame_hook); 2617EXPORT_SYMBOL_GPL(macvlan_handle_frame_hook);
2617 2618
2618static inline struct sk_buff *handle_macvlan(struct sk_buff *skb, 2619static 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)