Here is an updated patch for review. If you like this, then I'll post a series to back-port this to all the kernels...
Steve. --- 2.6.17 backport: simulate neighbour update events by snooping ARP packets Needed to support iWARP devices on backported kernels. This also allows using the current drivers/infiniband/core/addr.c which requires netevents as well. For each incoming ARP request or response, we add a destructor function to the skb. When the skb is freed (ie when the ARP subsystem has updated the neighbour entry if needed) our destructor function will get called and we can generate a NEIGH_UPDATE netevent. When the first consumer registers for netevents, we add an ARP packet filter to start snooping. When the last consumer unregisters, we remove the filter. Changes: - add the snoop code to the backport netevent.c file. - remove the backport patch to revert addr.c to snoop ARP packets. Signed-off-by: Steve Wise <[EMAIL PROTECTED]> --- .../backport/2.6.17/include/src/netevent.c | 67 ++++++++++++++++++++ .../2.6.17/addr_1_netevents_revert_to_2_6_17.patch | 76 ----------------------- 2 files changed, 65 insertions(+), 78 deletions(-) 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 35d02c3..26a0920 100644 --- a/kernel_addons/backport/2.6.17/include/src/netevent.c +++ b/kernel_addons/backport/2.6.17/include/src/netevent.c @@ -15,6 +15,55 @@ #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); + return; +} + +static int arp_recv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pkt, struct net_device *dev2) +{ + 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 ATOMIC_NOTIFIER_HEAD(netevent_notif_chain); @@ -30,8 +79,13 @@ static ATOMIC_NOTIFIER_HEAD(netevent_not int register_netevent_notifier(struct notifier_block *nb) { int err; - err = atomic_notifier_chain_register(&netevent_notif_chain, nb); + if (!err) { + mutex_lock(&lock); + if (count++ == 0) + dev_add_pack(&arp); + mutex_unlock(&lock); + } return err; } @@ -47,7 +101,16 @@ int register_netevent_notifier(struct no int unregister_netevent_notifier(struct notifier_block *nb) { - return atomic_notifier_chain_unregister(&netevent_notif_chain, nb); + int err; + + err = atomic_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_patches/backport/2.6.17/addr_1_netevents_revert_to_2_6_17.patch b/kernel_patches/backport/2.6.17/addr_1_netevents_revert_to_2_6_17.patch deleted file mode 100644 index 316d8d2..0000000 --- a/kernel_patches/backport/2.6.17/addr_1_netevents_revert_to_2_6_17.patch +++ /dev/null @@ -1,76 +0,0 @@ -commit e795d092507d571d66f2ec98d3efdc7dd284bf80 -Author: Tom Tucker <[EMAIL PROTECTED]> -Date: Sun Jul 30 20:44:19 2006 -0700 - - [NET] infiniband: Cleanup ib_addr module to use the netevents - - Signed-off-by: Tom Tucker <[EMAIL PROTECTED]> - Signed-off-by: Steve Wise <[EMAIL PROTECTED]> - Signed-off-by: David S. Miller <[EMAIL PROTECTED]> - -diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c -index 1205e80..d294bbc 100644 ---- a/drivers/infiniband/core/addr.c -+++ b/drivers/infiniband/core/addr.c -@@ -35,7 +35,6 @@ #include <linux/if_arp.h> - #include <net/arp.h> - #include <net/neighbour.h> - #include <net/route.h> --#include <net/netevent.h> - #include <rdma/ib_addr.h> - - MODULE_AUTHOR("Sean Hefty"); -@@ -327,22 +326,25 @@ void rdma_addr_cancel(struct rdma_dev_ad - } - EXPORT_SYMBOL(rdma_addr_cancel); - --static int netevent_callback(struct notifier_block *self, unsigned long event, -- void *ctx) -+static int addr_arp_recv(struct sk_buff *skb, struct net_device *dev, -+ struct packet_type *pkt, struct net_device *orig_dev) - { -- if (event == NETEVENT_NEIGH_UPDATE) { -- struct neighbour *neigh = ctx; -+ struct arphdr *arp_hdr; - -- if (neigh->dev->type == ARPHRD_INFINIBAND && -- (neigh->nud_state & NUD_VALID)) { -- set_timeout(jiffies); -- } -- } -+ arp_hdr = (struct arphdr *) skb->nh.raw; -+ -+ if (arp_hdr->ar_op == htons(ARPOP_REQUEST) || -+ arp_hdr->ar_op == htons(ARPOP_REPLY)) -+ set_timeout(jiffies); -+ -+ kfree_skb(skb); - return 0; - } - --static struct notifier_block nb = { -- .notifier_call = netevent_callback -+static struct packet_type addr_arp = { -+ .type = __constant_htons(ETH_P_ARP), -+ .func = addr_arp_recv, -+ .af_packet_priv = (void*) 1, - }; - - static int addr_init(void) -@@ -351,13 +353,13 @@ static int addr_init(void) - if (!addr_wq) - return -ENOMEM; - -- register_netevent_notifier(&nb); -+ dev_add_pack(&addr_arp); - return 0; - } - - static void addr_cleanup(void) - { -- unregister_netevent_notifier(&nb); -+ dev_remove_pack(&addr_arp); - destroy_workqueue(addr_wq); - } - - _______________________________________________ openib-general mailing list openib-general@openib.org http://openib.org/mailman/listinfo/openib-general To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general