[openib-general] [PATCH 02/12] ofed_1_2 Backport 2.6.17: Simulate neighbour update events by snooping ARP packets

Steve Wise swise at opengridcomputing.com
Thu Jan 25 11:13:25 PST 2007


Backport 2.6.17: 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 <swise at opengridcomputing.com>
---

 .../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 <tom at opengridcomputing.com>
-Date:   Sun Jul 30 20:44:19 2006 -0700
-
-    [NET] infiniband: Cleanup ib_addr module to use the netevents
-    
-    Signed-off-by: Tom Tucker <tom at opengridcomputing.com>
-    Signed-off-by: Steve Wise <swise at opengridcomputing.com>
-    Signed-off-by: David S. Miller <davem at davemloft.net>
-
-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);
- }
- 
-




More information about the general mailing list