A couple of unrelated incidents over the past couple of weeks have prompted me to put some words down on how a pretty well understood protocol in IPv4 has changed to a pretty misunderstood protocol in IPv6. Yup, that's right. ARP versus neighbor discovery.
I think that one of the problems people hit is that IPv6 neighbor discovery actually covers a range of different functions. For the purposes of this post I am only considering neighbor solicitations and solicited advertisements: i.e. the bits that replace ARP. Other goodness, such as router advertisements and duplicate address detection, I am treating as out of scope. I am also only considering the case of Ethernet, as that is by far the most common type of link in networks these days. When you restrict yourself to this subset to begin with neighbor discovery starts to look very familiar.
Lets consider ARP first. ARP is pretty simple. You send out a broadcast asking who has a specific IP address, and you get a unicast reply back telling you the answer. It can get more complicated than that, but that description covers most of the ARP you will ever see. So what are the problems?
The glaring one is the use of broadcast. An Ethernet broadcast will work its way through the whole of the layer 2 network. When an Ethernet card receives a broadcast (and every card will recieve every ARP request), the only thing it can do is punt it up to the next layer in the stack based on the Ethertype. You may hear other arguments against ARP, but basically it boils down to either the fact that every request hits the whole of your network or that every request causes a kernel interrupt on every box connected to the network.
When designing neighbour discovery in IPv6 thought was put into how this can be alleviated, and this is where most of the main differences between ARP and ND come in. Rather than broadcasting an ARP request, a neighbour solicitation will take the low-order 24 bits of the IPv6 address, and use this to construct a link-local multicast address to send the solicitation to. This will determine both the link-layer (MAC) destination as well as the destination IPv6 address used in the packet. The logic here is that if you are using stateless autoconfiguration, the low-order 24 bits of your IPv6 address will be the low-order 24 bits of your MAC address, and will be the same for every on-net prefix you have an address on and you only need one entry in your multicast filter list (more on this later).
Now multicast introduces a can of worms. What does Ethernet multicast actually mean? There are protocols/features (IGMP snooping, MLD) that will allow a switch to determine whether to flood a multicast frame through a port based on the groups that port subscribes to. These are valuable when you have busy multicast groups in your network, but most switches will fall back to a safe default of flooding all traffic. Because of this we can consider Ethernet multicast to be equivalent to broadcast at layer 2 in the majority of networks. Where this changes though is when the frame actually hits a network card. While a broadcast will always need to be passed up the stack, the chipset and driver should allow an application to specify which multicast MAC addresses it is interested in, and therefore the card can make a decision on whether to ignore the frame before generating an interrupt. So half a win here, right?.
Well actually that depends on your hardware and the way that the software is implemented. The MAC filter on most cards is quite limited. 128 is considered a good card, and numbers like 4 or 8 are a lot more common. What does this mean? Well, that again depends on the card. Sometimes it will be a simple list: interested in a MAC? Put it in the list and I will pass you frames forwarded to that MAC. Want more entries in the list than I have space for? Tough, you'll need to use promiscuous mode and get everything... Sometimes it is a hash table: Interested in a MAC? I will calculate a hash of the destination MAC (e.g. applying the FCS calculation against the destination MAC address to map it into a numerical bucket) and pass you all frames that match the same bucket. You can drop ones you aren't interested in. Other cards may have a filter list for unicast MACs but will have a flag allowing "promiscuous multicast" so that all multicast frames get punted upwards. In all cases, if the card forwards more than just those frames asked for, the software will need to make up for it; hopefully in the driver rather than punting the requirement all the way to user-space. In other words this isn't so much half a win as somewhere between parity and half a win. Maybe.
So is it all worth it? Personally I think it is. Sure there are arguments that the extra complexity doesn't actually come with much benefit but I would disagree here.
Neighbor Solicitation vs ARP Request and Neighbor Advertisement vs ARP Reply is a fairly clear mapping. It might not catch all the nuances but it is a pretty good start for troubleshooting. The fact that neighbor discovery actually uses ICMPv6 rather than residing in it's own layer parallel to IP may twist the noggins of us old-timers, but it makes more sense for new engineers coming in to networking. And while the jump from broadcast to multicast doesn't really give much advantage while today's network cards can't be relied on to filter things properly, but that is a problem that can be solved with pressure on vendors (which will come when people start growing LANS with /64s and don't have the prompt to evaluate the design that comes when you need to change the netmask). If we consider hardware not being where we want it a hard road-block we'll never get anything
Comments / abuse gratefully received :)