macvlan: use rx_handler_data pointer to store macvlan_port pointer V2
authorJiri Pirko <jpirko@redhat.com>
Tue, 15 Jun 2010 03:27:57 +0000 (03:27 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 15 Jun 2010 18:47:12 +0000 (11:47 -0700)
Register macvlan_port pointer as rx_handler data pointer. As macvlan_port is
removed from struct net_device, another netdev priv_flag is added to indicate
the device serves as a macvlan port.

Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Acked-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/macvlan.c
include/linux/if.h
include/linux/netdevice.h

index 87a3bf69c4a319386e106cdb568d6bd3890f8e14..e096875aa05527ac144856e7f593b36913a6b977 100644 (file)
@@ -40,6 +40,11 @@ struct macvlan_port {
        struct rcu_head         rcu;
 };
 
+#define macvlan_port_get_rcu(dev) \
+       ((struct macvlan_port *) rcu_dereference(dev->rx_handler_data))
+#define macvlan_port_get(dev) ((struct macvlan_port *) dev->rx_handler_data)
+#define macvlan_port_exists(dev) (dev->priv_flags & IFF_MACVLAN_PORT)
+
 static struct macvlan_dev *macvlan_hash_lookup(const struct macvlan_port *port,
                                               const unsigned char *addr)
 {
@@ -155,7 +160,7 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
        struct net_device *dev;
        unsigned int len;
 
-       port = rcu_dereference(skb->dev->macvlan_port);
+       port = macvlan_port_get_rcu(skb->dev);
        if (is_multicast_ether_addr(eth->h_dest)) {
                src = macvlan_hash_lookup(port, eth->h_source);
                if (!src)
@@ -530,14 +535,12 @@ static int macvlan_port_create(struct net_device *dev)
        INIT_LIST_HEAD(&port->vlans);
        for (i = 0; i < MACVLAN_HASH_SIZE; i++)
                INIT_HLIST_HEAD(&port->vlan_hash[i]);
-       rcu_assign_pointer(dev->macvlan_port, port);
 
-       err = netdev_rx_handler_register(dev, macvlan_handle_frame, NULL);
-       if (err) {
-               rcu_assign_pointer(dev->macvlan_port, NULL);
+       err = netdev_rx_handler_register(dev, macvlan_handle_frame, port);
+       if (err)
                kfree(port);
-       }
 
+       dev->priv_flags |= IFF_MACVLAN_PORT;
        return err;
 }
 
@@ -551,10 +554,10 @@ static void macvlan_port_rcu_free(struct rcu_head *head)
 
 static void macvlan_port_destroy(struct net_device *dev)
 {
-       struct macvlan_port *port = dev->macvlan_port;
+       struct macvlan_port *port = macvlan_port_get(dev);
 
+       dev->priv_flags &= ~IFF_MACVLAN_PORT;
        netdev_rx_handler_unregister(dev);
-       rcu_assign_pointer(dev->macvlan_port, NULL);
        call_rcu(&port->rcu, macvlan_port_rcu_free);
 }
 
@@ -633,12 +636,12 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
        if (!tb[IFLA_ADDRESS])
                random_ether_addr(dev->dev_addr);
 
-       if (lowerdev->macvlan_port == NULL) {
+       if (!macvlan_port_exists(lowerdev)) {
                err = macvlan_port_create(lowerdev);
                if (err < 0)
                        return err;
        }
-       port = lowerdev->macvlan_port;
+       port = macvlan_port_get(lowerdev);
 
        vlan->lowerdev = lowerdev;
        vlan->dev      = dev;
@@ -748,10 +751,11 @@ static int macvlan_device_event(struct notifier_block *unused,
        struct macvlan_dev *vlan, *next;
        struct macvlan_port *port;
 
-       port = dev->macvlan_port;
-       if (port == NULL)
+       if (!macvlan_port_exists(dev))
                return NOTIFY_DONE;
 
+       port = macvlan_port_get(dev);
+
        switch (event) {
        case NETDEV_CHANGE:
                list_for_each_entry(vlan, &port->vlans, list)
index be350e62a905438533b0231439d8d65fd53d7de4..31f2e27ebcd0d5e509d929f2e0e04d067ee32814 100644 (file)
@@ -73,6 +73,7 @@
 #define IFF_DONT_BRIDGE 0x800          /* disallow bridging this ether dev */
 #define IFF_IN_NETPOLL 0x1000          /* whether we are processing netpoll */
 #define IFF_DISABLE_NETPOLL    0x2000  /* disable netpoll at run-time */
+#define IFF_MACVLAN_PORT       0x4000  /* device used as macvlan port */
 
 #define IF_GET_IFACE   0x0001          /* for querying only */
 #define IF_GET_PROTO   0x0002
index 361ff1145cf1fcf2833648abce2c58afa780834f..5f231de2032fd8cb477e0724e530d8854b030fcf 100644 (file)
@@ -1049,8 +1049,6 @@ struct net_device {
 
        /* bridge stuff */
        struct net_bridge_port  *br_port;
-       /* macvlan */
-       struct macvlan_port     *macvlan_port;
        /* GARP */
        struct garp_port        *garp_port;