Patchwork [6/7] neigh: Add device constructor/destructor capability.

login
register
mail settings
Submitter David Miller
Date Dec. 1, 2011, 3:41 a.m.
Message ID <20111130.224151.1479303742039627135.davem@davemloft.net>
Download mbox | patch
Permalink /patch/128637/
State Accepted
Delegated to: David Miller
Headers show

Comments

David Miller - Dec. 1, 2011, 3:41 a.m.
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 |    2 ++
 net/core/neighbour.c      |   15 ++++++++++++++-
 2 files changed, 16 insertions(+), 1 deletions(-)
Ben Hutchings - Dec. 1, 2011, 7:08 p.m.
On Wed, 2011-11-30 at 22:41 -0500, David Miller wrote:
> 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 |    2 ++
>  net/core/neighbour.c      |   15 ++++++++++++++-
>  2 files changed, 16 insertions(+), 1 deletions(-)
> 
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 5462c2c..1c4ddb3 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -974,6 +974,8 @@ struct net_device_ops {
>  						    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);

ndo_neigh_destroy should return void, since the return value is not
used:

[...]
> @@ -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);

Patch

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 5462c2c..1c4ddb3 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -974,6 +974,8 @@  struct net_device_ops {
 						    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);
 };
 
 /*
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index ef750ff..cdf8dc3 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);