[openib-general] [PATCH 00/12] ofed_1_2 - Neighbour update support

Steve Wise swise at opengridcomputing.com
Thu Feb 1 09:12:01 PST 2007


Looks good.

Thanks,

Steve.


On Thu, 2007-02-01 at 14:10 +0200, Michael S. Tsirkin wrote:
> > Quoting Steve Wise <swise at opengridcomputing.com>:
> > Subject: [PATCH 00/12] ofed_1_2 - Neighbour update support
> > 
> > 
> > Michael/Vlad:
> > 
> > Here are the backports for snooping arp packets to generate neighbour
> > update netevents.  Also included is the addr.c patch to act on all valid
> > neigh update events.  If this series looks good to you then I'll push
> > this up and you all can pull it from my git tree.
> 
> This patches seems to have created a reference leak on each neighbour
> as a result ipoib interface could not be brought down.
> It also seems that RHASU2 backport was missing code.
> I pushed out the following:
> 
> 
> commit d140398db0da0beb3172e0ccf14ef3023cafec9c
> Author: Michael S. Tsirkin <mst at mellanox.co.il>
> Date:   Thu Feb 1 12:21:34 2007 +0200
> 
>     Fix neighbour reference leak in netevent.c
>     
>     Signed-off-by: Michael S. Tsirkin <mst at mellanox.co.il>
> 
> diff --git a/kernel_addons/backport/2.6.11/include/src/netevent.c b/kernel_addons/backport/2.6.11/include/src/netevent.c
> index 6a8df29..0d26662 100644
> --- a/kernel_addons/backport/2.6.11/include/src/netevent.c
> +++ b/kernel_addons/backport/2.6.11/include/src/netevent.c
> @@ -38,8 +38,10 @@ static void destructor(struct sk_buff *skb)
>  	arp_ptr = skb->nh.raw + sizeof(struct arphdr) + skb->dev->addr_len;
>  	memcpy(&gw, arp_ptr, 4);
>  	n = neigh_lookup(&arp_tbl, &gw, skb->dev);
> -	if (n)
> +	if (n) {
>  		call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n);
> +		neigh_release(n);
> +	}
>  	return;
>  }
>  
> diff --git a/kernel_addons/backport/2.6.12/include/src/netevent.c b/kernel_addons/backport/2.6.12/include/src/netevent.c
> index 6a8df29..0d26662 100644
> --- a/kernel_addons/backport/2.6.12/include/src/netevent.c
> +++ b/kernel_addons/backport/2.6.12/include/src/netevent.c
> @@ -38,8 +38,10 @@ static void destructor(struct sk_buff *skb)
>  	arp_ptr = skb->nh.raw + sizeof(struct arphdr) + skb->dev->addr_len;
>  	memcpy(&gw, arp_ptr, 4);
>  	n = neigh_lookup(&arp_tbl, &gw, skb->dev);
> -	if (n)
> +	if (n) {
>  		call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n);
> +		neigh_release(n);
> +	}
>  	return;
>  }
>  
> diff --git a/kernel_addons/backport/2.6.13/include/src/netevent.c b/kernel_addons/backport/2.6.13/include/src/netevent.c
> index 6a8df29..0d26662 100644
> --- a/kernel_addons/backport/2.6.13/include/src/netevent.c
> +++ b/kernel_addons/backport/2.6.13/include/src/netevent.c
> @@ -38,8 +38,10 @@ static void destructor(struct sk_buff *skb)
>  	arp_ptr = skb->nh.raw + sizeof(struct arphdr) + skb->dev->addr_len;
>  	memcpy(&gw, arp_ptr, 4);
>  	n = neigh_lookup(&arp_tbl, &gw, skb->dev);
> -	if (n)
> +	if (n) {
>  		call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n);
> +		neigh_release(n);
> +	}
>  	return;
>  }
>  
> diff --git a/kernel_addons/backport/2.6.14/include/src/netevent.c b/kernel_addons/backport/2.6.14/include/src/netevent.c
> index 188283c..17a12ff 100644
> --- a/kernel_addons/backport/2.6.14/include/src/netevent.c
> +++ b/kernel_addons/backport/2.6.14/include/src/netevent.c
> @@ -38,8 +38,10 @@ static void destructor(struct sk_buff *skb)
>  	arp_ptr = skb->nh.raw + sizeof(struct arphdr) + skb->dev->addr_len;
>  	memcpy(&gw, arp_ptr, 4);
>  	n = neigh_lookup(&arp_tbl, &gw, skb->dev);
> -	if (n)
> +	if (n) {
>  		call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n);
> +		neigh_release(n);
> +	}
>  	return;
>  }
>  
> diff --git a/kernel_addons/backport/2.6.15/include/src/netevent.c b/kernel_addons/backport/2.6.15/include/src/netevent.c
> index 188283c..17a12ff 100644
> --- a/kernel_addons/backport/2.6.15/include/src/netevent.c
> +++ b/kernel_addons/backport/2.6.15/include/src/netevent.c
> @@ -38,8 +38,10 @@ static void destructor(struct sk_buff *skb)
>  	arp_ptr = skb->nh.raw + sizeof(struct arphdr) + skb->dev->addr_len;
>  	memcpy(&gw, arp_ptr, 4);
>  	n = neigh_lookup(&arp_tbl, &gw, skb->dev);
> -	if (n)
> +	if (n) {
>  		call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n);
> +		neigh_release(n);
> +	}
>  	return;
>  }
>  
> diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/src/netevent.c b/kernel_addons/backport/2.6.15_ubuntu606/include/src/netevent.c
> index 188283c..17a12ff 100644
> --- a/kernel_addons/backport/2.6.15_ubuntu606/include/src/netevent.c
> +++ b/kernel_addons/backport/2.6.15_ubuntu606/include/src/netevent.c
> @@ -38,8 +38,10 @@ static void destructor(struct sk_buff *skb)
>  	arp_ptr = skb->nh.raw + sizeof(struct arphdr) + skb->dev->addr_len;
>  	memcpy(&gw, arp_ptr, 4);
>  	n = neigh_lookup(&arp_tbl, &gw, skb->dev);
> -	if (n)
> +	if (n) {
>  		call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n);
> +		neigh_release(n);
> +	}
>  	return;
>  }
>  
> diff --git a/kernel_addons/backport/2.6.16/include/src/netevent.c b/kernel_addons/backport/2.6.16/include/src/netevent.c
> index 188283c..17a12ff 100644
> --- a/kernel_addons/backport/2.6.16/include/src/netevent.c
> +++ b/kernel_addons/backport/2.6.16/include/src/netevent.c
> @@ -38,8 +38,10 @@ static void destructor(struct sk_buff *skb)
>  	arp_ptr = skb->nh.raw + sizeof(struct arphdr) + skb->dev->addr_len;
>  	memcpy(&gw, arp_ptr, 4);
>  	n = neigh_lookup(&arp_tbl, &gw, skb->dev);
> -	if (n)
> +	if (n) {
>  		call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n);
> +		neigh_release(n);
> +	}
>  	return;
>  }
>  
> diff --git a/kernel_addons/backport/2.6.16_sles10/include/src/netevent.c b/kernel_addons/backport/2.6.16_sles10/include/src/netevent.c
> index 188283c..17a12ff 100644
> --- a/kernel_addons/backport/2.6.16_sles10/include/src/netevent.c
> +++ b/kernel_addons/backport/2.6.16_sles10/include/src/netevent.c
> @@ -38,8 +38,10 @@ static void destructor(struct sk_buff *skb)
>  	arp_ptr = skb->nh.raw + sizeof(struct arphdr) + skb->dev->addr_len;
>  	memcpy(&gw, arp_ptr, 4);
>  	n = neigh_lookup(&arp_tbl, &gw, skb->dev);
> -	if (n)
> +	if (n) {
>  		call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n);
> +		neigh_release(n);
> +	}
>  	return;
>  }
>  
> diff --git a/kernel_addons/backport/2.6.17/include/src/netevent.c b/kernel_addons/backport/2.6.17/include/src/netevent.c
> index 26a0920..4c67de1 100644
> --- a/kernel_addons/backport/2.6.17/include/src/netevent.c
> +++ b/kernel_addons/backport/2.6.17/include/src/netevent.c
> @@ -38,8 +38,10 @@ static void destructor(struct sk_buff *skb)
>  	arp_ptr = skb->nh.raw + sizeof(struct arphdr) + skb->dev->addr_len;
>  	memcpy(&gw, arp_ptr, 4);
>  	n = neigh_lookup(&arp_tbl, &gw, skb->dev);
> -	if (n)
> +	if (n) {
>  		call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n);
> +		neigh_release(n);
> +	}
>  	return;
>  }
>  
> diff --git a/kernel_addons/backport/2.6.5_sles9_sp3/include/src/netevent.c b/kernel_addons/backport/2.6.5_sles9_sp3/include/src/netevent.c
> index 57a23ab..90fce0c 100644
> --- a/kernel_addons/backport/2.6.5_sles9_sp3/include/src/netevent.c
> +++ b/kernel_addons/backport/2.6.5_sles9_sp3/include/src/netevent.c
> @@ -39,8 +39,10 @@ static void destructor(struct sk_buff *skb)
>  	arp_ptr = skb->nh.raw + sizeof(struct arphdr) + skb->dev->addr_len;
>  	memcpy(&gw, arp_ptr, 4);
>  	n = neigh_lookup(&arp_tbl, &gw, skb->dev);
> -	if (n)
> +	if (n) {
>  		call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n);
> +		neigh_release(n);
> +	}
>  	return;
>  }
>  
> diff --git a/kernel_addons/backport/2.6.9_U2/include/src/netevent.c b/kernel_addons/backport/2.6.9_U2/include/src/netevent.c
> index 5ffadd1..1589300 100644
> --- a/kernel_addons/backport/2.6.9_U2/include/src/netevent.c
> +++ b/kernel_addons/backport/2.6.9_U2/include/src/netevent.c
> @@ -13,10 +13,59 @@
>   *	Fixes:
>   */
>  
> -#include <linux/module.h>
> -#include <linux/skbuff.h>
>  #include <linux/rtnetlink.h>
>  #include <linux/notifier.h>
> +#include <linux/mutex.h>
> +#include <linux/if.h>
> +#include <linux/netdevice.h>
> +#include <linux/if_arp.h>
> +
> +#include <net/arp.h>
> +#include <net/neighbour.h>
> +#include <net/route.h>
> +#include <net/netevent.h>
> +
> +static DEFINE_MUTEX(lock);
> +static int count;
> +
> +static void destructor(struct sk_buff *skb)
> +{
> +	struct neighbour *n;
> +	u8 *arp_ptr;
> +	__be32 gw;
> +
> +	/* Pull the SPA */
> +	arp_ptr = skb->nh.raw + sizeof(struct arphdr) + skb->dev->addr_len;
> +	memcpy(&gw, arp_ptr, 4);
> +	n = neigh_lookup(&arp_tbl, &gw, skb->dev);
> +	if (n) {
> +		call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n);
> +		neigh_release(n);
> +	}
> +	return;
> +}
> +
> +static int arp_recv(struct sk_buff *skb, struct net_device *dev,
> +			 struct packet_type *pkt)
> +{
> +	struct arphdr *arp_hdr;
> +	u16 op;
> +
> +	arp_hdr = (struct arphdr *) skb->nh.raw;
> +	op = ntohs(arp_hdr->ar_op);
> +
> +	if ((op == ARPOP_REQUEST || op == ARPOP_REPLY) && !skb->destructor)
> +		skb->destructor = destructor;
> +
> +	kfree_skb(skb);
> +	return 0;
> +}
> +
> +static struct packet_type arp = {
> +	.type = __constant_htons(ETH_P_ARP),
> +	.func = arp_recv,
> +	.af_packet_priv = (void *)1,
> +};
>  
>  static struct notifier_block *netevent_notif_chain;
>  
> @@ -34,6 +83,12 @@ int register_netevent_notifier(struct notifier_block *nb)
>  	int err;
>  
>  	err = notifier_chain_register(&netevent_notif_chain, nb);
> +	if (!err) {
> +		mutex_lock(&lock);
> +		if (count++ == 0)
> +			dev_add_pack(&arp);
> +		mutex_unlock(&lock);
> +	}
>  	return err;
>  }
>  
> @@ -49,7 +104,16 @@ int register_netevent_notifier(struct notifier_block *nb)
>  
>  int unregister_netevent_notifier(struct notifier_block *nb)
>  {
> -	return notifier_chain_unregister(&netevent_notif_chain, nb);
> +	int err;
> +
> +	err = notifier_chain_unregister(&netevent_notif_chain, nb);
> +	if (!err) {
> +		mutex_lock(&lock);
> +		if (--count == 0)
> +			dev_remove_pack(&arp);
> +		mutex_unlock(&lock);
> +	}
> +	return err;
>  }
>  
>  /**
> diff --git a/kernel_addons/backport/2.6.9_U3/include/src/netevent.c b/kernel_addons/backport/2.6.9_U3/include/src/netevent.c
> index 5ffadd1..1589300 100644
> --- a/kernel_addons/backport/2.6.9_U3/include/src/netevent.c
> +++ b/kernel_addons/backport/2.6.9_U3/include/src/netevent.c
> @@ -13,10 +13,59 @@
>   *	Fixes:
>   */
>  
> -#include <linux/module.h>
> -#include <linux/skbuff.h>
>  #include <linux/rtnetlink.h>
>  #include <linux/notifier.h>
> +#include <linux/mutex.h>
> +#include <linux/if.h>
> +#include <linux/netdevice.h>
> +#include <linux/if_arp.h>
> +
> +#include <net/arp.h>
> +#include <net/neighbour.h>
> +#include <net/route.h>
> +#include <net/netevent.h>
> +
> +static DEFINE_MUTEX(lock);
> +static int count;
> +
> +static void destructor(struct sk_buff *skb)
> +{
> +	struct neighbour *n;
> +	u8 *arp_ptr;
> +	__be32 gw;
> +
> +	/* Pull the SPA */
> +	arp_ptr = skb->nh.raw + sizeof(struct arphdr) + skb->dev->addr_len;
> +	memcpy(&gw, arp_ptr, 4);
> +	n = neigh_lookup(&arp_tbl, &gw, skb->dev);
> +	if (n) {
> +		call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n);
> +		neigh_release(n);
> +	}
> +	return;
> +}
> +
> +static int arp_recv(struct sk_buff *skb, struct net_device *dev,
> +			 struct packet_type *pkt)
> +{
> +	struct arphdr *arp_hdr;
> +	u16 op;
> +
> +	arp_hdr = (struct arphdr *) skb->nh.raw;
> +	op = ntohs(arp_hdr->ar_op);
> +
> +	if ((op == ARPOP_REQUEST || op == ARPOP_REPLY) && !skb->destructor)
> +		skb->destructor = destructor;
> +
> +	kfree_skb(skb);
> +	return 0;
> +}
> +
> +static struct packet_type arp = {
> +	.type = __constant_htons(ETH_P_ARP),
> +	.func = arp_recv,
> +	.af_packet_priv = (void *)1,
> +};
>  
>  static struct notifier_block *netevent_notif_chain;
>  
> @@ -34,6 +83,12 @@ int register_netevent_notifier(struct notifier_block *nb)
>  	int err;
>  
>  	err = notifier_chain_register(&netevent_notif_chain, nb);
> +	if (!err) {
> +		mutex_lock(&lock);
> +		if (count++ == 0)
> +			dev_add_pack(&arp);
> +		mutex_unlock(&lock);
> +	}
>  	return err;
>  }
>  
> @@ -49,7 +104,16 @@ int register_netevent_notifier(struct notifier_block *nb)
>  
>  int unregister_netevent_notifier(struct notifier_block *nb)
>  {
> -	return notifier_chain_unregister(&netevent_notif_chain, nb);
> +	int err;
> +
> +	err = notifier_chain_unregister(&netevent_notif_chain, nb);
> +	if (!err) {
> +		mutex_lock(&lock);
> +		if (--count == 0)
> +			dev_remove_pack(&arp);
> +		mutex_unlock(&lock);
> +	}
> +	return err;
>  }
>  
>  /**
> diff --git a/kernel_addons/backport/2.6.9_U4/include/src/netevent.c b/kernel_addons/backport/2.6.9_U4/include/src/netevent.c
> index 6a8df29..0d26662 100644
> --- a/kernel_addons/backport/2.6.9_U4/include/src/netevent.c
> +++ b/kernel_addons/backport/2.6.9_U4/include/src/netevent.c
> @@ -38,8 +38,10 @@ static void destructor(struct sk_buff *skb)
>  	arp_ptr = skb->nh.raw + sizeof(struct arphdr) + skb->dev->addr_len;
>  	memcpy(&gw, arp_ptr, 4);
>  	n = neigh_lookup(&arp_tbl, &gw, skb->dev);
> -	if (n)
> +	if (n) {
>  		call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n);
> +		neigh_release(n);
> +	}
>  	return;
>  }
>  
> 





More information about the general mailing list