diff options
author | David Miller <davem@davemloft.net> | 2011-07-25 04:01:38 +0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-12-01 03:48:03 +0400 |
commit | da6a8fa0275e2178c44a875374cae80d057538d1 (patch) | |
tree | 6a9df6b3b9e268ca463fdb47d9041883acc923ea /net/core | |
parent | 869759b9e4160fb8a8d25bc3b4ce3b658523aebb (diff) | |
download | linux-da6a8fa0275e2178c44a875374cae80d057538d1.tar.xz |
neigh: Add device constructor/destructor capability.
If the neigh entry has device private state, it will need
constructor/destructor ops.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/neighbour.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index ef750ff7497e..cdf8dc34f0ba 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -489,6 +489,14 @@ struct neighbour *neigh_create(struct neigh_table *tbl, const void *pkey, 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) { @@ -692,6 +700,8 @@ static inline void neigh_parms_put(struct neigh_parms *parms) */ void neigh_destroy(struct neighbour *neigh) { + struct net_device *dev = neigh->dev; + 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; - 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); |