[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