[openib-general] [PATCH] sdp: replace ip_dev_find with dev_base scan (was Re: ip_dev_find resolution?)

Michael S. Tsirkin mst at mellanox.co.il
Mon Dec 12 06:56:29 PST 2005


Quoting Michael S. Tsirkin <mst at mellanox.co.il>:
> Subject: Re: ip_dev_find resolution?
> 
> Quoting r. Hal Rosenstock <halr at voltaire.com>:
> > Subject: Re: ip_dev_find resolution?
> > 
> > On Tue, 2005-12-06 at 12:56, Michael S. Tsirkin wrote:
> > > Actually, I wander whether instead of ip_dev_find we can just
> > > 
> > >                 read_lock(&dev_base_lock);
> > >                 for (dev = dev_base; dev; dev = dev->next) {
> > > 
> > > and check the ip address?
> > 
> > working off the ip_ptr and ip6_ptr ?
> 
> Yes.
> 
> > > If this works, this has the advantage of supporting IPv6 as well.
> > 
> > This was introduced at one point and we subsequently changed to
> > ip_dev_find. I forget exactly why this was but can dig it out if no
> one
> > recalls.
> 
> Please do.

Any updates? Hal?

I've coded the following up since I grew tired of patching my kernels
to run sdp. Seems to work fine for me, can someone please speak up
on why this isnt a good idea for CMA, as well?

Ultimately, IMO this also has a better chance to be generalizable to IPv6.

--- 

Replace ip_dev_find (which isnt exported in 2.6.14) with full device list
lookup.

Signed-off-by: Michael S. Tsirkin <mst at mellanox.co.il>

Index: linux-2.6.14.3/drivers/infiniband/ulp/sdp/sdp_link.c
===================================================================
--- linux-2.6.14.3.orig/drivers/infiniband/ulp/sdp/sdp_link.c
+++ linux-2.6.14.3/drivers/infiniband/ulp/sdp/sdp_link.c
@@ -346,6 +346,41 @@ static int sdp_link_path_rec_get(struct 
 	return 0;
 }
 
+static int tryaddrmatch(struct net_device *dev, u32 s_addr, u32 d_addr)
+{
+	struct in_ifaddr **ifap;
+	struct in_ifaddr *ifa;
+	struct in_device *in_dev;
+	int rc = -ENETUNREACH;
+	__be32 addr;
+
+	if (dev->type != ARPHRD_INFINIBAND)
+		return rc;
+
+	in_dev = in_dev_get(dev);
+	if (!in_dev)
+		return rc;
+
+	addr = (ZERONET(s_addr) || LOOPBACK(s_addr)) ? d_addr : s_addr;
+
+	/* Hack to enable using SDP on addresses such as 127.0.0.1 */
+	if (ZERONET(addr) || LOOPBACK(addr)) {
+		rc = (dev->flags & IFF_UP) ? 0 : -ENETUNREACH;
+		goto done;
+	}
+
+	for (ifap = &in_dev->ifa_list; (ifa = *ifap); ifap = &ifa->ifa_next) {
+		if (s_addr == ifa->ifa_address) {
+			rc = 0;
+			break; /* found */
+		}
+	}
+
+done:
+	in_dev_put(in_dev);
+	return rc;
+}
+
 /*
  * do_link_path_lookup - resolve an ip address to a path record
  */
@@ -406,17 +441,9 @@ static void do_link_path_lookup(struct s
 		     rt->u.dst.neighbour->dev->name,
 		     rt->rt_src, rt->rt_dst, rt->rt_gateway,
 		     rt->u.dst.neighbour->nud_state);
-	/*
-	 * device needs to be a valid IB device. Check for loopback.
-	 * In case of loopback find a valid IB device on which to
-	 * direct the loopback traffic.
-	 */
-	if (rt->u.dst.neighbour->dev->flags & IFF_LOOPBACK)
-		dev = ip_dev_find(rt->rt_src);
-	else {
-		dev = rt->u.dst.neighbour->dev;
-		dev_hold(dev);
-	}
+
+	dev = rt->u.dst.neighbour->dev;
+	dev_hold(dev);
 
 	/*
 	 * check for IB device or loopback, the later requires extra
@@ -433,13 +460,11 @@ static void do_link_path_lookup(struct s
 	if (dev->flags & IFF_LOOPBACK) {
 		dev_put(dev);
 		read_lock(&dev_base_lock);
-		for (dev = dev_base; dev; dev = dev->next) {
-			if (dev->type == ARPHRD_INFINIBAND &&
-			    (dev->flags & IFF_UP)) {
+		for (dev = dev_base; dev; dev = dev->next)
+			if (!tryaddrmatch(dev, rt->rt_src, rt->rt_dst)) {
 				dev_hold(dev);
 				break;
 			}
-		}
 		read_unlock(&dev_base_lock);
 	}
 

-- 
MST



More information about the general mailing list