diff options
Diffstat (limited to 'drivers/net/macvlan.c')
-rw-r--r-- | drivers/net/macvlan.c | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 40faa368b07a..4e238afab4a3 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) |
@@ -243,7 +239,7 @@ netdev_tx_t macvlan_start_xmit(struct sk_buff *skb, | |||
243 | int ret; | 239 | int ret; |
244 | 240 | ||
245 | ret = macvlan_queue_xmit(skb, dev); | 241 | ret = macvlan_queue_xmit(skb, dev); |
246 | if (likely(ret == NET_XMIT_SUCCESS)) { | 242 | if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { |
247 | txq->tx_packets++; | 243 | txq->tx_packets++; |
248 | txq->tx_bytes += len; | 244 | txq->tx_bytes += len; |
249 | } else | 245 | } else |
@@ -282,7 +278,7 @@ static int macvlan_open(struct net_device *dev) | |||
282 | if (macvlan_addr_busy(vlan->port, dev->dev_addr)) | 278 | if (macvlan_addr_busy(vlan->port, dev->dev_addr)) |
283 | goto out; | 279 | goto out; |
284 | 280 | ||
285 | err = dev_unicast_add(lowerdev, dev->dev_addr); | 281 | err = dev_uc_add(lowerdev, dev->dev_addr); |
286 | if (err < 0) | 282 | if (err < 0) |
287 | goto out; | 283 | goto out; |
288 | if (dev->flags & IFF_ALLMULTI) { | 284 | if (dev->flags & IFF_ALLMULTI) { |
@@ -294,7 +290,7 @@ static int macvlan_open(struct net_device *dev) | |||
294 | return 0; | 290 | return 0; |
295 | 291 | ||
296 | del_unicast: | 292 | del_unicast: |
297 | dev_unicast_delete(lowerdev, dev->dev_addr); | 293 | dev_uc_del(lowerdev, dev->dev_addr); |
298 | out: | 294 | out: |
299 | return err; | 295 | return err; |
300 | } | 296 | } |
@@ -308,7 +304,7 @@ static int macvlan_stop(struct net_device *dev) | |||
308 | if (dev->flags & IFF_ALLMULTI) | 304 | if (dev->flags & IFF_ALLMULTI) |
309 | dev_set_allmulti(lowerdev, -1); | 305 | dev_set_allmulti(lowerdev, -1); |
310 | 306 | ||
311 | dev_unicast_delete(lowerdev, dev->dev_addr); | 307 | dev_uc_del(lowerdev, dev->dev_addr); |
312 | 308 | ||
313 | macvlan_hash_del(vlan); | 309 | macvlan_hash_del(vlan); |
314 | return 0; | 310 | return 0; |
@@ -332,11 +328,11 @@ static int macvlan_set_mac_address(struct net_device *dev, void *p) | |||
332 | if (macvlan_addr_busy(vlan->port, addr->sa_data)) | 328 | if (macvlan_addr_busy(vlan->port, addr->sa_data)) |
333 | return -EBUSY; | 329 | return -EBUSY; |
334 | 330 | ||
335 | err = dev_unicast_add(lowerdev, addr->sa_data); | 331 | err = dev_uc_add(lowerdev, addr->sa_data); |
336 | if (err) | 332 | if (err) |
337 | return err; | 333 | return err; |
338 | 334 | ||
339 | dev_unicast_delete(lowerdev, dev->dev_addr); | 335 | dev_uc_del(lowerdev, dev->dev_addr); |
340 | 336 | ||
341 | macvlan_hash_change_addr(vlan, addr->sa_data); | 337 | macvlan_hash_change_addr(vlan, addr->sa_data); |
342 | } | 338 | } |
@@ -748,6 +744,9 @@ static int macvlan_device_event(struct notifier_block *unused, | |||
748 | list_for_each_entry_safe(vlan, next, &port->vlans, list) | 744 | list_for_each_entry_safe(vlan, next, &port->vlans, list) |
749 | vlan->dev->rtnl_link_ops->dellink(vlan->dev, NULL); | 745 | vlan->dev->rtnl_link_ops->dellink(vlan->dev, NULL); |
750 | break; | 746 | break; |
747 | case NETDEV_PRE_TYPE_CHANGE: | ||
748 | /* Forbid underlaying device to change its type. */ | ||
749 | return NOTIFY_BAD; | ||
751 | } | 750 | } |
752 | return NOTIFY_DONE; | 751 | return NOTIFY_DONE; |
753 | } | 752 | } |