[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