13

What linux DHCPv6 client can I set up so it requests a prefix on one interface and then on all the other interfaces it will give out addresses (or if requested, a smaller prefix delegation)? It would also need to set up the routes and router advertisements.

If there's not a way to do this, what is the IPv6 version of programming an IPv4 router to do NAT, wherever it is put? Basically, I'm trying to understand how a manufacturer would set up their IPv6 capable routers so a customer can plug them in and they would work. I'm not talking about actual NAT in IPv6, but a way for a router to have a DHCPv6 prefix delegation client which would take the prefix it received and break it into smaller prefixes and addresses and run a DHCPv6 server for each separate downstream link.

I added a diagram:

Diagram with 9 computers. #2, #4, #6, #7, and #9 are DHCPv6 clients. #1 is assigned 2001:db8:1200::/40 and giving out /48 prefix delegations. #3, #5, and #8 are DHCPv6 servers and clients at the same time as they are requesting prefixes.

Is there (a) piece(s) of software I can run on Linux that could be configured once and then put in place number 3, 5, or 8 and it would automatically set itself up depending on the prefix it was delegated?

3 Answers 3

7

This isn't a complete answer, since I'm still working through some of the problems, but here's what I've got so far, trying to deploy a near-identical setup (though for somewhat different reasons).

The good news is: it can be done, within the specs. In fact, the specs were explicitly designed to encourage this sort of subdelegation of prefixes, largely to avoid the need for painful multiple NAT layers while still allowing flexibility in how networks are structured.

The bad news is: there are no "out-of-the-box" single pieces of software that will request a prefix from an upstream, configure addresses and routes locally, and hand out sub-prefixes to downstream networks. Hell, it doesn't even appear possible to wire up pre-existing pieces of software in Linux (without patching) to do what needs to be done. Worst of all, it doesn't look like anyone really cares about this.

What I've got setup and working so far looks like this:

  • I'm using WIDE DHCPv6 client (dhcp6c) to request a prefix from the "upstream" network; I chose this client over ISC's DHCP client because, at the time I set it up, it was the only DHCPv6 client that would automatically assign addresses out of the received prefix to other interfaces. I would like to think that other DHCP clients have improved since then, but I couldn't be bothered to check at this point.

    Unfortunately, it doesn't expose the delegated prefix details to its external hook script, meaning that you can't (easily) rewrite your "downstream" dhcpd config.

  • ISC DHCP server (in v6 mode) to assign prefixes to the "downstream" network. I chose this because WIDE's DHCP server, as far as I can tell, can only delegate prefixes statically, not dynamically. It's relatively easy to configure ISC DHCP server to do dynamic prefix delegation, surprisingly; something as simple as this will do the trick:

    subnet6 2001:db8:1234:ffff::/64 {
      prefix6 2001:db8:1234:a000:: 2001:db8:c0f:aff0:: /60;
    }
    

    This will listen on whatever interface has an address in 2001:db8:1234:ffff::/64 and will hand out /60s from the range specified. As long as you can coerce dhcp6c to update the above config (next!), you can automatically update the dhcpd config when your delegated super-prefix changes.

  • dhcp6c will, as previously mentioned, take a script parameter in its config file, to run when a DHCPv6 response is received. Unfortunately, it only exposes parameters like the SIP server, and DNS resolvers, not useful info like the prefix that's been delegated. So, I've got the following scriptlet to do that for me:

    #!/bin/sh
    
    (sleep 3;
    
    base_prefix="$(ip -6 ad sh eth0 | grep 'scope global' | cut -d ' ' -f 6 | cut -d : -f 1-4 | sed 's/00$//')"
    
    if [ "$base_prefix" = "" ]; then
      exit 0
    fi
    
    cat <<-EOF >/etc/dhcp/dhcpd6.conf
    default-lease-time 1800;
    max-lease-time 7200;
    
    subnet6 ${base_prefix}00::/64 {
      prefix6 ${base_prefix}a0:: ${base_prefix}f0:: /60;
    }
    EOF
    
    svc -t /etc/service/dhcp6d) &
    
    exit 0
    

    Doing all the work in a sub-shell means that I can wait a little while (the sleep 3) for the DHCP client to actually configure the interface (it appears to run the script before configuring the interface). It works reliably enough. Note that my ISP delegates me a /56, hence why I'm only stripping the lasy two zeroes off the received prefix. If you're lucky enough to get a whole /48, the pipeline to assign base_prefix would be a lot simpler.

What doesn't already exist, and which I'm pretty sure requires patching source code, is setting up routes when a prefix gets delegated. So far as I can see, no DHCP server has the built-in ability to add the route automatically (I've carefully examined WIDE dhcp6s, it certainly can't do it, and I can't find anything on the 'tubes to suggest that ISC DHCP does it). There isn't even the ability to run an external command that takes the prefix being delegated and the client's link-local address (ISC DHCP has on commit { execute(...) }, but no way to get the client's link-local address to pass out).

The problem is that without this crucial bit of functionality, the router that's making the delegation can't know where to route the traffic for the prefix to afterwards. That's a fairly fundamental limitation, and I'm rather stunned that nobody appears to have dealt with this problem before -- or if they have, they're keeping really quiet about it.

I've just developed a patch to ISC DHCP to provide an extra "data expression" to the eval functionality; this allows me to shell out to an external program which can then add/remove routes on prefix allocation and release/expiry; the patch is available at https://github.com/mpalmer/isc-dhcp/commit/4c8ae763bcf83c9068d57a5d9f570690a581b6d6 (against ISC DHCP 4.3.1); I don't have a script to add the route (yet), but I'll probably add it under contrib in that branch once I get it written.

ADDENDUM: It turns out that further modification was needed to allow routes to be removed again; that has now been added to the client-address-data-expression branch, along with a small Ruby script that shows how it can all be combined together.

5
  • Do you know Dibbler? Perhaps it is an alternative since it supports prefix delegation in its client and server - and it is packaged e.g. for Fedora/EPEL. See also Section 6.8.11 in the user guide for an example how to configure the prefix delegation in the client (optional hook-script, up/downlink interfaces, ask parameters etc.). Jan 15, 2017 at 21:54
  • I am well aware of dibbler. Is it capable of setting up the routes on the server when the prefix is delegated? ISC DHCP, too, supports prefix delegation in its client and server, and it is packaged also. It is the routing that is the sticking point.
    – womble
    Jan 19, 2017 at 7:49
  • DIbbler has the script directive for setting up hooks - that mechanism looks suitable for creating routes on the server when the prefix is delegated (cf. Section 4.8). Jan 19, 2017 at 9:00
  • Have you actually done it? Because ISC DHCP also has hook scripts, and well...
    – womble
    Jan 19, 2017 at 9:19
  • 1
    Well, you complained that dhcp6c doesn't expose the PREFIX information - in contrast: dibbler does that. And it does even more: I've done some tests with dibbler-client and with a simple configuration (without script) it does automatically configure a route for the delegated prefix on the downstream interface. It also generates a radvd.conf that can be used to start a radvd on the downstream interface. When configuring an external script the script can do some additional setup steps - available environment variables are e.g. PREFIX*, SRV_OPTION* (e.g. DNS server), DOWNLINK_* ... Jan 29, 2017 at 16:15
1

The program that does prefix delegation is radvd (Router Advertisement Daemon). Other IPv6 hosts on the link should automatically configure a globally routeable address from the announced prefix.

IPv6 does not require NAT as hosts which require Internet access are expected to have globally routeable addresses. You need to be careful in your Firewall rules to prevent infiltration from the Internet.

ISPs are expected to give out a /48 or /56 network block to their customers. This requires a bit of smarts on the ISP side to ensure each router gets a unique block. One /64 block will likely be used as the uplink to the IPS's network. The router is then free to announce as many /64s as from the rest of the block as it wishes. Likely only one would be used in this scenario.

There is an IPv6 DHCP implementation as well.

One quick setup which has been done is to configure the router to use 6to4 tunneling. radvd will autoconfigure for this setup, but it requires a publicly routeable IPv4 address.

EDIT: While radvd can't subdelegate prefixes it can automatically announce a /64 prefix based on an available routeable addresses. It also has Base6to4 to automatically announce the 6to4 prefix of the router. Subdelegation requires some planning and is beyond what should be expected of a plug and play configuration.

EDIT2: Like IPv4 IPv6 does not have a method to determine which network belongs on the networks connected to eth1 or eth2 base on the address assigned to the eth0 interface. Once you have multiple network segments you need to begin managing the addresses assigned to each segment. The good news is this can usually be done once.

IPv6 makes it easier as 5 and 8 can easily be given /49 or /50 subnets of the /48 delegated to 3. An alternate approach would be to configure 3, 5, and 8 as bridges on the same /64 subnet. In such a configuration, they would work as switches. Automatic subnet generation risk routers 5 and 8 both choosing to delegate the same subnet.

Plug and pray routers for home use just use a default private address block. They quickly break down when configured as shown in your diagram. Mixing routers with different default address blocks may work. Otherwise you need to ensure each router has different block of addresses.

3
  • I'm pretty sure radvd can't do Prefix delegation, at least not by itself. It has to be configured to have a flag that points to using DHCPv6 and then the DHCPv6 server can delegate prefixes. I'm looking for software that can request a prefix delegation and then subdelegate that, including smaller prefix delegations.
    – Azendale
    Jan 1, 2012 at 22:04
  • In reply to edit: With IPv4 a consumer can plug in a router and connect computers through it. IPv4 uses NAT to do this. How does an IPv6 router do this? Doesn't it need a block of addresses to assign to its downstream? My question is looking for software that asks for a block of addresses and then assigns that to the downstream, whether that downstream is clients or another router with more clients behind it.
    – Azendale
    Jan 2, 2012 at 1:28
  • So, I guess the one situation I saw of NAT behind NAT was a case of lucky. I guess this is an opportunity for IPv6 to do better than IPv4. From asking this question at tunnelbroker.net/forums/index.php?topic=2212.0 , it is apparent that what I'm asking can be done while still following protocol. So I'm still looking for software to do what I want.
    – Azendale
    Jan 3, 2012 at 2:58
-1

Looks like you need a routing protocol such as RIPng. You could install quagga on those boxes, configure the interfaces that need the routing protocol (once) and off you go.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.