Merge branch 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.git] / drivers / net / macvlan.c
index 9a939d8..87e8d4c 100644 (file)
@@ -145,19 +145,15 @@ static void macvlan_broadcast(struct sk_buff *skb,
 }
 
 /* called under rcu_read_lock() from netif_receive_skb */
-static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
+static struct sk_buff *macvlan_handle_frame(struct macvlan_port *port,
+                                           struct sk_buff *skb)
 {
        const struct ethhdr *eth = eth_hdr(skb);
-       const struct macvlan_port *port;
        const struct macvlan_dev *vlan;
        const struct macvlan_dev *src;
        struct net_device *dev;
        unsigned int len;
 
-       port = rcu_dereference(skb->dev->macvlan_port);
-       if (port == NULL)
-               return skb;
-
        if (is_multicast_ether_addr(eth->h_dest)) {
                src = macvlan_hash_lookup(port, eth->h_source);
                if (!src)
@@ -243,7 +239,7 @@ netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
        int ret;
 
        ret = macvlan_queue_xmit(skb, dev);
-       if (likely(ret == NET_XMIT_SUCCESS)) {
+       if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {
                txq->tx_packets++;
                txq->tx_bytes += len;
        } else
@@ -638,11 +634,18 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
 
        err = register_netdevice(dev);
        if (err < 0)
-               return err;
+               goto destroy_port;
 
        list_add_tail(&vlan->list, &port->vlans);
        netif_stacked_transfer_operstate(lowerdev, dev);
+
        return 0;
+
+destroy_port:
+       if (list_empty(&port->vlans))
+               macvlan_port_destroy(lowerdev);
+
+       return err;
 }
 EXPORT_SYMBOL_GPL(macvlan_common_newlink);