aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorDavid Miller <davem@davemloft.net>2011-07-25 00:01:38 +0000
committerDavid S. Miller <davem@davemloft.net>2011-11-30 18:48:03 -0500
commitda6a8fa0275e2178c44a875374cae80d057538d1 (patch)
tree6a9df6b3b9e268ca463fdb47d9041883acc923ea /net/core
parentatm: clip: Convert over to neighbour_priv() (diff)
downloadlinux-dev-da6a8fa0275e2178c44a875374cae80d057538d1.tar.xz
linux-dev-da6a8fa0275e2178c44a875374cae80d057538d1.zip
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.c15
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);