Looks good.

Thanks,

Steve.


On Thu, 2007-02-01 at 14:10 +0200, Michael S. Tsirkin wrote:
> > Quoting Steve Wise <[EMAIL PROTECTED]>:
> > 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 <[EMAIL PROTECTED]>
> Date:   Thu Feb 1 12:21:34 2007 +0200
> 
>     Fix neighbour reference leak in netevent.c
>     
>     Signed-off-by: Michael S. Tsirkin <[EMAIL PROTECTED]>
> 
> 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;
>  }
>  
> 


_______________________________________________
openib-general mailing list
[email protected]
http://openib.org/mailman/listinfo/openib-general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to