IPv6 NDP Proxy // ndppd

A /64 prefix is the smallest block an ISP should hand out. If they hand you one of these, chances are they are not really routing it to you. This would also mean that you’ll not be able to route things further by using radvd, for example. Instead, the ISP’s router would try to find out your connected interface’s link-layer address by using the Neighbor Discovery Protocol, NDP.

Basically this involves responding to a Neighbor Solicitation Message, with a Neighbor Advertisement Message – providing the link-layer address of the interface with that configured IPv6 address.

Anyway – let’s pretend you have a server running Xen, with several domUs, and you want each of them to have it’s own IPv6 address. The simplest solution here would be to set up a bridge, so that the domUs can respond to the solicitation messages themselves.

However, there are cases when you can’t use bridging and must rely on routing. For instance, if the port your interface is connected to has some sort of MAC filtering. In this case your dom0 must respond to Neighbor Solicitation Messages for IPs it doesn’t really have.

This can be done in vanilla Linux by enabling proxy_ndp, then adding each IP you wish to route to the neighbor proxy table using:

ip -6 neigh add proxy <some ip> dev <some dev>

For this to work you need to do this for each single IP. You can’t specify a prefix, which can make it difficult to maintain. Not only that – you can’t even list the entries in the neighbor proxy table.

There are currently two good solutions to the problem.

ndppd, or NDP Proxy Daemon, which proxies certain NDP packets between two or more interfaces. It has support for matching prefixes, querying internal interfaces for matching IPs, and static matching so it can work like npd6. You can read more about ndppd here: http://www.priv.nu/projects/ndppd/.

- and -

npd6, which you can read more about here. This is where I got my inspiration from. Since I was in need of features it didn’t have, and because I needed something to do, I decided to write my own implementation that would better suit my needs. (See above).

** Update **

ndppd version 0.2.2 has now been released. It supports automatic detection of the outgoing interface (when forwarding) by reading the routing table.

Thanks to Gabriel Kerneis, ndppd is now being maintained as a package for OpenWrt. As the package is quite new, it’s currently only available in a snapshot build of OpenWrt.