netfilter: ipset: Use proper timeout value to jiffies conversion
[firefly-linux-kernel-4.4.55.git] / drivers / net / macvlan.c
index d7c0bc62da7fd56584fc4c265a79b8f301d72fc5..d6aeaa5f25eaa86df9780d03783b548631e92262 100644 (file)
@@ -70,16 +70,17 @@ static void macvlan_hash_add(struct macvlan_dev *vlan)
        hlist_add_head_rcu(&vlan->hlist, &port->vlan_hash[addr[5]]);
 }
 
-static void macvlan_hash_del(struct macvlan_dev *vlan)
+static void macvlan_hash_del(struct macvlan_dev *vlan, bool sync)
 {
        hlist_del_rcu(&vlan->hlist);
-       synchronize_rcu();
+       if (sync)
+               synchronize_rcu();
 }
 
 static void macvlan_hash_change_addr(struct macvlan_dev *vlan,
                                        const unsigned char *addr)
 {
-       macvlan_hash_del(vlan);
+       macvlan_hash_del(vlan, true);
        /* Now that we are unhashed it is safe to change the device
         * address without confusing packet delivery.
         */
@@ -237,10 +238,8 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
 
                dest = macvlan_hash_lookup(port, eth->h_dest);
                if (dest && dest->mode == MACVLAN_MODE_BRIDGE) {
-                       unsigned int length = skb->len + ETH_HLEN;
-                       int ret = dest->forward(dest->dev, skb);
-                       macvlan_count_rx(dest, length,
-                                        ret == NET_RX_SUCCESS, 0);
+                       /* send to lowerdev first for its network taps */
+                       vlan->forward(vlan->lowerdev, skb);
 
                        return NET_XMIT_SUCCESS;
                }
@@ -345,7 +344,7 @@ static int macvlan_stop(struct net_device *dev)
        dev_uc_del(lowerdev, dev->dev_addr);
 
 hash_del:
-       macvlan_hash_del(vlan);
+       macvlan_hash_del(vlan, !dev->dismantle);
        return 0;
 }
 
@@ -584,26 +583,18 @@ static int macvlan_port_create(struct net_device *dev)
        err = netdev_rx_handler_register(dev, macvlan_handle_frame, port);
        if (err)
                kfree(port);
-
-       dev->priv_flags |= IFF_MACVLAN_PORT;
+       else
+               dev->priv_flags |= IFF_MACVLAN_PORT;
        return err;
 }
 
-static void macvlan_port_rcu_free(struct rcu_head *head)
-{
-       struct macvlan_port *port;
-
-       port = container_of(head, struct macvlan_port, rcu);
-       kfree(port);
-}
-
 static void macvlan_port_destroy(struct net_device *dev)
 {
        struct macvlan_port *port = macvlan_port_get(dev);
 
        dev->priv_flags &= ~IFF_MACVLAN_PORT;
        netdev_rx_handler_unregister(dev);
-       call_rcu(&port->rcu, macvlan_port_rcu_free);
+       kfree_rcu(port, rcu);
 }
 
 static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])