DHCPv6 and link-local IPv6 interface addresses
  • 25 Oct 2018
  • 4 Minutes to read
  • Contributors
  • Dark
    Light
  • PDF

DHCPv6 and link-local IPv6 interface addresses

  • Dark
    Light
  • PDF

Article Summary

Problem:

For DHCPv6 server, if we want dhcpd listening on a certain interface, it requires a subnet declaration in dhcpd.conf which covers the interface's address; otherwise, the dhcpd server will refuse to listen on the specified interface. For example, we see this message when starting the DHCP server:

No subnet6 declaration for eth0 (fe80::20c:29ff:fe1a:cc12).
** Ignoring requests on eth0. If this is not what
you want, please write a subnet6 declaration
in your dhcpd.conf file for the network segment
to which interface eth0 is attached. **

This problem is mostly ISC DHCP-specific; Kea solves the problem differently. For comparison, see Kea answer section below.

Answer (ISC DHCP):

It's not possible to have dhcpd listen on an interface if it's not declared via subnet6.

The message:

No subnet6 declaration for eth0 (fe80::20c:29ff:fe1a:cc12)

... means that there is no known IPv6 subnet defined in dhcpd.conf that matches the current configuration of eth0.

When starting, the server expects to be able to find at least one IPv6 interface that has been declared in the configuration file, otherwise (quite reasonably - since it can do nothing without at least one interface on which to be working) it will refuse to start. It will report an error on each one it finds that it doesn't have a subnet declaration for.

When configuring dhcpd, in your subnet declarations, you're describing your network rather than simply saying 'for pool X use interface Y'. The subnet declarations are telling dhcpd which interfaces it needs to handle.

Note: In principle, the DHCPv6 protocol operates on link-local addresses, so strictly speaking a server doesn't require to have a global address configured on its interfaces. However, the DHCPv6 component in dhcpd was implemented to follow the same logic as its DHCPv4 counterpart and thus it requires a global IPv6 address configured on its network interfaces. Kea does not have that limitation. See Kea section below.

Here's an example of how to do this in a production environment.  Let's assume that there is a subnet 2001:db8:1::/48.  You would do the following to start serving IPv6 addresses from that pool:

  1. Assign an address from that pool to one of your interfaces, e.g:
ip addr add 2001:db8:1::1/48 dev eth0
  1. Add the following entry to your server config file:
subnet6 2001:db8:1::/48 {
     range6 2001:db8:1::2 2001:db8:1::ff;
}
  1. Start your server.

The server will detect that there is a 2001:db8:1::/48 pool in your network. It will discover that your server is connected to that pool over eth0 interface as its address belongs to that pool. The server will then start listening on that interface and will provide addresses from 2001:db8:12 to 2001:db8:1ff. (Note that the address that is used by the DHCP server itself was carefully excluded from that range). So now, what to do about any other interfaces on the DHCP server machine? If those interfaces have only link-local addresses (i.e. belonging to fe80::/10 prefix), the server will complain about not being able to detect to which subnet they are connected. You can do one of 3 things here:

  1. Disable the interface (ifconfig eth0 down). dhcpd will ignore down interfaces.

  2. Assign (possibly a dummy) address to that interface, then define an empty subnet (i.e. a subnet6 without any range6 in it).

  3. Ignore the message as long as you have at least one interface that server is able to provide configuration over.

We plan to skip this error message for link local addresses in future versions of dhcpv6, but the bottom line is still that you need to have at least one interface with an IPv6 address with a scope larger than link-local (which means global in most cases) assigned to it.

Answer (ISC Kea):

Kea does not have the limitations of ISC DHCP in the sense that it is able to operate with only IPv6 link-local addresses configured; it has interface definitions and subnet information separated. The interfaces are specified using interfaces in the "interfaces-config" section. The list allows specifying just the interface name (link local socket will be opened) or iterfacename/ipv6-address (sockets will be opened on both link local and global addresses). Opening socket on (presumably global) unicast address is useful for two cases: first, when server unicast option is configuration, and second, when relays are configured to relay traffic to a unicast address.

You can configure network interfaces regardless of whether you do or do not expect to receive traffic from directly connected clients over that interface. There's a very good reason for that approach. Kea DHCPv6 server can listen on several interfaces and could receive traffic from only directly connected clients (direct traffic), via relays only (relayed traffic), or a mix of both. Information about local subnet is only needed when direct traffic is expected; therefore, having a subnet configured locally is not needed in all cases. Having said that, if there is local traffic and the server does not have a global IPv6 address that belongs to the subnet (that's slightly uncommon, but a valid configuration), Kea must be told which subnet (or subnets if there are multiple interfaces) are available locally. This can be specified using optional "interface" parameter for a subnet.

For example:

"Dhcp6": {

    // This tells Kea to listen on two interfaces and also bind to global IPv6 address.
    "interfaces-config": {
**"interfaces": [ "eth0", "eth1/2001:db8::1" ]**     },
 
`
`    "subnet6": [

        // This subnet definition tells Kea that the subnet is accessible via its eth0 
        // interface directly (not via relay).
        {
            "subnet": "2001:db8:beef::/48",
            **`"interface": "eth0"`** ,
            ...
        }
    ],
    ...
}