Routing in IPv6 is a much misunderstood thing! Not so much between routers, which works pretty much the same way as it always has with IPv4. The problem is the first hop – with IPv6 there may be several “default routers”, and selecting the first destination for an outbound packet is a process that seems shrouded in mystery. Read on for enlightenment!
“First hop routing”, as I call it, has developed over time. Initially, if a router advertised a non-zero default router lifetime, that router would be one of the default routers, end of story. Later, route information options and router preferences were added. So first hop routing has been a bit of a moving target. And even though it is basically a very simple thing, it has a lots of ifs and buts, so any description tends to be long and involved. Perhaps this description will be different.
On link or not on link?
Before we start, let’s look at the concept of “on-link”. A prefix is on-link if addresses in that prefix are (or should be) reachable directly, without going through a router. The whole idea of routing is irrelevant in this case – a host uses neighbor discovery to find out the layer 2 address of the destination and sends it there directly.
The flip side is that addresses which are not on-link can only be reached through a router – a gateway. But how to tell which addresses are on-link? Well, routers can tell hosts this directly through prefix information options in the router advertisements. There is a per-prefix “on-link” flag that, if set, means the given prefix is indeed on-link. If the flag is not set (or there is no information about a prefix at all), then the prefix may be on-link or it may not. In practice, this means it is assumed to be off-link.
Aside from a prefix being advertised as on-link, a host may decide to treat a given address as on-link if it sees a neighbor advertisement from it, sees a neighbor discovery about it, or receives a router redirect for it.
A word on reachability
“Reachability” in this context means “has a REACHABLE status in the neighbor discovery cache”. If a default router is not reachable then it will not be selected as a default router.
All communication between routers and hosts (at least about first hop routing) is via link local addresses.
IPv6 has been designed to allow for multiple routers on one link. All of these routers may be able to reach the outside world; or maybe some can and some cannot. Perhaps some routers have paths to parts of the outside world that other routers cannot reach. So if I have an outbound packet that I want to deliver (and assuming it is not to an on-link address), which router should I send it to?
This is where “first hop routing” comes in. I keep putting it in quotation marks because although it is for all practical purposes routing, it is in fact (at least conceptually) completely separate from and subordinate to any real routing. If you set up a static route to a particular address, for example, that route trumps all “first hop routing”. Routers do not do any first hop routing – only hosts do it.
Hosts maintain a list of all possible default routers. The list is populated by the host as it sees router advertisements come past. When a default router is needed, the list is gone through until a reachable router is found. Any routers that get rejected because they are unreachable are probed for reachability after (or at the same time as) the packet is sent on to the reachable router. Because otherwise equal default routers are selected in round-robin fashion, all unreachable routers will eventually be probed for reachability in turn. If/when they become reachable they will be used.
If all available default routers are unreachable, then packets aimed at the outside world will be dropped and a “destination unreachable” ICMPv6 message will be issued.
The simplest case
Let’s start with the simplest case, where there is one router advertising a non-zero default router lifetime. Because there is only one router, router preference is irrelevant. For any addresses not known to be on-link, this one router will be selected as the default router. If it’s not reachable, packets will be dropped.
A slightly less simple case
Now let’s look at the case where two routers are on the same link, and both are advertising a non-zero default router lifetime. In this case, either router could be selected – but which one will be selected?
Hosts remember which next-hop addresses have been used for which destination addresses or prefixes, and will use the same next-hop address for a particular destination until something changes. So if a next-hop is already known for an address, that next-hop will be used. The next-hops are updated or deleted if a default router becomes unreachable, stops being a default router, changes preference and so on. Entries are added to the list when default routers are selected for particular destinations.
In the absence of a known next-hop for a destination, and all things being equal, any default router may be selected. Each time a choice must be made, the next default router will be chosen, in round-robin fashion.
But all things might not be equal. If the destination is known to be on-link, the host will try to deliver the packet directly, resolving the layer 2 address via neighbor discovery. If either default router is not currently in “reachable” state, the other will be selected, because reachable default routers are preferred. If either default router has a higher preference than the other, then the default router with the higher preference will be chosen.
If no default router can be chosen, and the address is not known to be on-link, then the destination is unreachable.
Prefix and Router Information Options
A Prefix Information Option (PIO) contains information about a single prefix. From a first hop routing perspective, the important items are the prefix and the on-link flag.
A Route Information Option (PIO) contains information about a single route, defined as a prefix, and gives a router preference for that specific route.
Some operating systems – notably Linux – need to be configured to accept RIOs with prefix lengths longer than zero (that is, prefixes other than ::/0, the default route), as a sort of basic security precaution. For Linux do this (or make the equivalent change in /etc/sysctl.conf):
sudo sysctl -w net/ipv6/conf/all/accept_ra_rt_info_max_plen=64
PIOs and RIOs are sent inside router advertisements, and are optional. A router advertisement need not contain any PIOs or RIOs at all.
An important aspect of route and prefix information options is that the information in them overrides any information carried in their enclosing router advertisement. This means that, in combination with each other or in combination with the values in their enclosing router advertisements, you can achieve quite fine-grained control over what routers will be used for what destination prefixes.
Controlling first hop routing
Given all the above information, we can see the knobs and levers available to us for controlling first hop routing.
Using default router lifetimes
If a router advertises a non-zero default router lifetime, then that router may be used as a default router. If not – then not. Notice that this is regardless of any prefixes it advertises!
The default router lifetimes in router advertisements provide only very crude control – a router either is, or is not, a default router. Finer-grained control is possible with route information options.
Using router preferences
Use router preferences to prefer one default router over another. There are only three levels of preference, “high”, “medium” and “low”. The default is “medium”.
By way of example, let’s say you have two routers, A and B, both of which can reach the Internet. You want all traffic to go via router A, but if router A is down, you want all traffic to go via router B.
To achieve this, you might configure router A to advertise a default router preference of “high” and the other to advertise the default router preference of “medium”. As long as router A remains reachable, all traffic will go through router A. If it becomes unreachable, all traffic will go through router B.
Once again, this is independent of any prefixes the routers advertise. Finer-grained control is possible with route information options.
Using the on-link flag in Prefix Information Options
The main purpose of setting the on-link flag in prefix information options is to let hosts know that they should use neighbor discovery to find addresses in those prefixes. Otherwise they would have to send packets to a default router, even though they could directly forward the packet on into the local subnet. In fact, that is one function of router redirects – to inform hosts that an address they tried to reach via a router is in fact on-link.
One rather odd thing you could do with the on-link flag would be to put the same prefix on more than one router interface! If you did not set the on-link flag for the prefix in the advertisements from those interfaces, hosts would forward all packets for the prefix to the router. Hosts would get redirects for addresses on their own link; the router would deliver anything addressed to addresses on the other link(s). Fun, but in no sense civilised.
In short, the on-link flag is not something you would generally use to control first-hop routing.
Using route information options
Route information options (RIOs) give you finer grained control than default router preferences, but work the same way. The difference is that the route preferences and route lifetimes in RIOs apply only to specific prefixes.
Let’s say you have two routers, A and B, both of which can reach the Internet, but A is connected through ISPA and B is connected through ISPB. You want all traffic for ISPA to go via router A, and all traffic for ISPB to go via router B. For traffic going to other destinations you don’t care – it can go via either router.
To achieve this, you might configure both routers to advertise a default router preference of “medium”, and add route information options to the router advertisements from the two routers. On router A you configure RIOs with a “high” router preference for ISPA’s prefixes; on router B you configure RIOs with a “high” router preference for ISPB’s prefixes.
You can also set the router preference value in an RIO to a lower value than the enclosing router advertisement. In this way to can choose to have a router carry all traffic except that going to specific prefixes.
Similar things can be achieved using the route lifetime in an RIO. To make a router carry only specific prefixes, set the default router lifetime to zero, and send RIOs with non-zero route lifetimes for specific prefixes.
Alternatively, make the router carry all except specific prefixes by setting the default router lifetime to some value other than zero, and send RIOs with zero route lifetimes for specific prefixes.