core
core copied to clipboard
OPNsense does not add IPv6 route for delegated prefix (KEA)
Important notices
Before you add a new report, we ask you kindly to acknowledge the following:
- [x] I have read the contributing guide lines at https://github.com/opnsense/core/blob/master/CONTRIBUTING.md
- [x] I am convinced that my issue is new after having checked both open and closed issues at https://github.com/opnsense/core/issues?q=is%3Aissue
Describe the bug
OPNsense does not add a ipv6-route to the delegated prefix. I am using KEA DHCPv6. Other BSD-based (blue) firewall does add route correctly.
Tip: to validate your setup was working with the previous version, use opnsense-revert (https://docs.opnsense.org/manual/opnsense_tools.html#opnsense-revert)
To Reproduce
Steps to reproduce the behavior: Configure prefix-delegation in KEA DHCPv6 and have a client router request prefix.
- [ ]
Expected behavior
A route to the delegated prefix should be installed in the routing table.
Software version used and hardware type if relevant, e.g.:
OPNsense 25.7.a_428-amd64. FreeBSD 14.2-RELEASE-p3 OpenSSL 3.0.16
VM on Proxmox VE
^ red line denotes where route is missing.
Also, the ISC DHCPv6 daemon DOES add the route. Adding the route is the responsibility of the firewall software vendor to write a script. Kea DHCPv6 does provide a hooks script that is called at all lease state changes; a Hook script is needed to manipulate the route table. They also provide a sample script to handle this directly.
The absence of this feature makes Kea DHCPv6 unusable for any cases it is assigning Delegated Prefixes (PD).
Given these facts, I believe this should be considered a bug.
I would also like to request that while this work is done, this can be investigated from an HA standpoint: For effective HA to work, two things need to happen: the lease database needs to be sync'ed with the HA peer (which I believe IS supported currently), AND the routes for PDs need to be in the system route table (either already present, or quickly loaded when the backup becomes the master -- there should be no issues with the routes in the table even when in backup, and this could even be considered preferable). I do not know if Kea has direct mechanisms for this (eg, call the hook script on the backup server as well as the master).
@kusznir If it’s a bug or a feature I’ll gladly leave up for debate, but I don’t mind offering some inspiration so you can work on a pull-request.
Similar discussion about isc back in 2018: https://forum.opnsense.org/index.php?topic=7719.0
The hack mentioned there:
https://github.com/opnsense/core/blob/53518740d5c53768ab4ba570643fe7899306c610/src/etc/inc/plugins.inc.d/dhcpd.inc#L1168
And the script in question:
https://github.com/opnsense/core/blob/master/src/opnsense/scripts/dhcp/prefixes.sh
Note that PD routes are not added with ISC DHCPv6 either, if the requesting client doesn't have an DHCPv6-assigned address, as also mentioned in the linked thread:
It seems that routes for delegated prefixes are currently created by parsing the DHCPv6 lease file and matching address assignments (IA_NA) to prefix delegations (IA_PD). I think this was implemented pre-OPNsense, probably as some kind of "quick fix to get it working somehow". This seems fundamentally broken to me since it relies on the requesting router also requesting an address. Also, it is considered best practice to use link-local addresses as next-hop on links between routers, not Global Unicast addresses.
This is more relevant now with the announcement from Android, that they've implemented RFC 9663 aka DHCPv6-PD-to-the-client and RFC 9762 aka RA PIO P-flag:
- https://mailarchive.ietf.org/arch/msg/v6ops/Sq5TadeSsMQ-0uEWrdem3A1wDh0/
- https://android-developers.googleblog.com/2025/09/simplifying-advanced-networking-with.html
Here Android never does an IA_NA request, in fact it might not even do SLAAC, so the routes must definitely be added with the link-local as next hop.
I know this isn't strictly on-topic on this feature request, but if/when someone touches it, it's probably worth doing it "properly" for both DHCPv6 services.
ChromeOS recently started requesting a DHCPv6 PD prefix (if available) with only a local SLAAC address as well. The prefix is used for itself and the Linux and Android VMs running on top of it. If a v6 PD is not available, ChromeOS falls back to IPv6 NAT.
Without the PD prefix added to the router's routing table, anything using the PD prefix will be unroutable.
I had to disable DHCPv6 PD on my LAN as this entirely broke IPv6 for all ChromeOS devices.
Feature ticket is https://github.com/opnsense/core/issues/9135 -- it's on the roadmap for 26.1.
Also, it is considered best practice to use link-local addresses as next-hop on links between routers, not Global Unicast addresses.
In fact -- for ISC DHCPv6 -- you can already do this. Add a static mapping for the link local and it's able to route to the prefix.
Cheers, Franco
In fact -- for ISC DHCPv6 -- you can already do this. Add a static mapping for the link local and it's able to route to the prefix.
@fichtner does this require manually creating a static mapping for each client, or is there an automated way to handle this?
There's no automatic way to handle this since the link local is not really predictable how it is currently integrated. In theory the client first responds to DHCP link local but that information may be lost in a reboot/rebind so technically the DHCP server needs a way to store that.
Create one static mapping on the relevant DHCP interface with a link local address and prefixes.php can pick it up for a route.
We've also had discussions around Kea integration asking how well this really works in practice when there is virtually no integration for it (besides scripting to do "anything" one can think of).
Cheers, Franco
This issue has been automatically timed-out (after 180 days of inactivity).
For more information about the policies for this repository, please read https://github.com/opnsense/core/blob/master/CONTRIBUTING.md for further details.
If someone wants to step up and work on this issue, just let us know, so we can reopen the issue and assign an owner to it.
Actually this has been solved, and we target the LLA with the IA_PD route:
https://github.com/opnsense/core/pull/9330