[openib-general] [RFC] IB address translation using ARP
Sean Hefty
mshefty at ichips.intel.com
Mon Oct 10 11:43:51 PDT 2005
Tom Tucker wrote:
> I think I understand where I'm upside down now. In my world,
> you don't know which interface to send the ARP request on
> until you've identified the local interface and you can't
> identify the local interface until you've looked up the route.
> Not all interface have a path to all remote peers.
We have the same restriction. I lookup the route based on the destination IP
address to get the local interface.
> In your world, you can't look up the path record until you've
> identified the remote GID. What I don't get is, if you have more
> than one IB interface, which interface do you submit your IPoIB ARP
> request on? All of them?
It's based on the device returned by the route lookup. I've attached the
relevant code portion below. If the code below fails, I generate an ARP, wait
for the reply, then re-execute the code.
> Not sure what a "normal IP ARP" message is. In my world, ARP and
> IP are peer protocols. ARP does not sit on top of IP, nor is it a
> special kind of IP message. Forgive my ignorance, but does IPoIB
> have ARP built into it?
I was being confusing. The ARP is sent on the IPoIB net_device to map an IP
address to the remote hardware address. There's nothing special about the ARP.
- Sean
static int addr_resolve_remote(struct sockaddr_in *src_in,
struct sockaddr_in *dst_in,
struct ib_addr *addr)
{
u32 src_ip = src_in->sin_addr.s_addr;
u32 dst_ip = dst_in->sin_addr.s_addr;
struct flowi fl;
struct rtable *rt;
struct neighbour *neigh;
int ret;
memset(&fl, 0, sizeof fl);
fl.nl_u.ip4_u.daddr = dst_ip;
fl.nl_u.ip4_u.saddr = src_ip;
ret = ip_route_output_key(&rt, &fl);
if (ret)
goto out;
neigh = neigh_lookup(&arp_tbl, &dst_ip, rt->idev->dev);
if (!neigh) {
ret = -ENODATA;
goto err1;
}
if (!(neigh->nud_state & NUD_VALID)) {
ret = -ENODATA;
goto err2;
}
if (!src_ip) {
src_in->sin_family = dst_in->sin_family;
src_in->sin_addr.s_addr = rt->rt_src;
}
addr->sgid = *(union ib_gid *) (neigh->dev->dev_addr + 4);
addr->dgid = *(union ib_gid *) (neigh->ha + 4);
addr->pkey = addr_get_pkey(neigh->dev);
err2:
neigh_release(neigh);
err1:
ip_rt_put(rt);
out:
return ret;
}
static void addr_send_arp(struct sockaddr_in *dst_in)
{
struct rtable *rt;
struct flowi fl;
u32 dst_ip = dst_in->sin_addr.s_addr;
memset(&fl, 0, sizeof fl);
fl.nl_u.ip4_u.daddr = dst_ip;
if (ip_route_output_key(&rt, &fl))
return;
arp_send(ARPOP_REQUEST, ETH_P_ARP, dst_ip, rt->idev->dev, rt->rt_src,
NULL, rt->idev->dev->dev_addr, NULL);
ip_rt_put(rt);
}
More information about the general
mailing list