neigh: Add device constructor/destructor capability.
authorDavid Miller <davem@davemloft.net>
Mon, 25 Jul 2011 00:01:38 +0000 (00:01 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 30 Nov 2011 23:48:03 +0000 (18:48 -0500)
If the neigh entry has device private state, it will need
constructor/destructor ops.

Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/netdevice.h
net/core/neighbour.c

index 5462c2c..1c4ddb3 100644 (file)
@@ -974,6 +974,8 @@ struct net_device_ops {
                                                    netdev_features_t features);
        int                     (*ndo_set_features)(struct net_device *dev,
                                                    netdev_features_t features);
                                                    netdev_features_t features);
        int                     (*ndo_set_features)(struct net_device *dev,
                                                    netdev_features_t features);
+       int                     (*ndo_neigh_construct)(struct neighbour *n);
+       int                     (*ndo_neigh_destroy)(struct neighbour *n);
 };
 
 /*
 };
 
 /*
index ef750ff..cdf8dc3 100644 (file)
@@ -489,6 +489,14 @@ struct neighbour *neigh_create(struct neigh_table *tbl, const void *pkey,
                goto out_neigh_release;
        }
 
                goto out_neigh_release;
        }
 
+       if (dev->netdev_ops->ndo_neigh_construct) {
+               error = dev->netdev_ops->ndo_neigh_construct(n);
+               if (error < 0) {
+                       rc = ERR_PTR(error);
+                       goto out_neigh_release;
+               }
+       }
+
        /* Device specific setup. */
        if (n->parms->neigh_setup &&
            (error = n->parms->neigh_setup(n)) < 0) {
        /* Device specific setup. */
        if (n->parms->neigh_setup &&
            (error = n->parms->neigh_setup(n)) < 0) {
@@ -692,6 +700,8 @@ static inline void neigh_parms_put(struct neigh_parms *parms)
  */
 void neigh_destroy(struct neighbour *neigh)
 {
  */
 void neigh_destroy(struct neighbour *neigh)
 {
+       struct net_device *dev = neigh->dev;
+
        NEIGH_CACHE_STAT_INC(neigh->tbl, destroys);
 
        if (!neigh->dead) {
        NEIGH_CACHE_STAT_INC(neigh->tbl, destroys);
 
        if (!neigh->dead) {
@@ -707,7 +717,10 @@ void neigh_destroy(struct neighbour *neigh)
        skb_queue_purge(&neigh->arp_queue);
        neigh->arp_queue_len_bytes = 0;
 
        skb_queue_purge(&neigh->arp_queue);
        neigh->arp_queue_len_bytes = 0;
 
-       dev_put(neigh->dev);
+       if (dev->netdev_ops->ndo_neigh_destroy)
+               dev->netdev_ops->ndo_neigh_destroy(neigh);
+
+       dev_put(dev);
        neigh_parms_put(neigh->parms);
 
        NEIGH_PRINTK2("neigh %p is destroyed.\n", neigh);
        neigh_parms_put(neigh->parms);
 
        NEIGH_PRINTK2("neigh %p is destroyed.\n", neigh);