Merge branch 'linus' into cont_syslog
[safe/jmp/linux-2.6] / drivers / net / macvlan.c
index 445e73c..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
@@ -282,7 +278,7 @@ static int macvlan_open(struct net_device *dev)
        if (macvlan_addr_busy(vlan->port, dev->dev_addr))
                goto out;
 
-       err = dev_unicast_add(lowerdev, dev->dev_addr);
+       err = dev_uc_add(lowerdev, dev->dev_addr);
        if (err < 0)
                goto out;
        if (dev->flags & IFF_ALLMULTI) {
@@ -294,7 +290,7 @@ static int macvlan_open(struct net_device *dev)
        return 0;
 
 del_unicast:
-       dev_unicast_delete(lowerdev, dev->dev_addr);
+       dev_uc_del(lowerdev, dev->dev_addr);
 out:
        return err;
 }
@@ -308,7 +304,7 @@ static int macvlan_stop(struct net_device *dev)
        if (dev->flags & IFF_ALLMULTI)
                dev_set_allmulti(lowerdev, -1);
 
-       dev_unicast_delete(lowerdev, dev->dev_addr);
+       dev_uc_del(lowerdev, dev->dev_addr);
 
        macvlan_hash_del(vlan);
        return 0;
@@ -332,11 +328,11 @@ static int macvlan_set_mac_address(struct net_device *dev, void *p)
                if (macvlan_addr_busy(vlan->port, addr->sa_data))
                        return -EBUSY;
 
-               err = dev_unicast_add(lowerdev, addr->sa_data);
+               err = dev_uc_add(lowerdev, addr->sa_data);
                if (err)
                        return err;
 
-               dev_unicast_delete(lowerdev, dev->dev_addr);
+               dev_uc_del(lowerdev, dev->dev_addr);
 
                macvlan_hash_change_addr(vlan, addr->sa_data);
        }
@@ -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);