I've also reproduced this. The problem is in the dhcrelay6 implementation
The relevant OPNsense interface has both:
2406:xxxx:xxxx:b170::1/64
fe80::250:56ff:feaa:bb70
but the Relay-Forward sent to the DHCPv6 server contains:
Link-address: fe80::250:56ff:feaa:bb70
My Windows DHCP server receives the Relay-Forward but can't associate that link-local address with the 2406:xxxx:xxxx:b170::/64 scope, so it sends no reply. For comparison, a Dell switch relaying to the same DHCPv6 server correctly uses its client facing GUA as link-address and Windows immediately returns a Relay-Reply.
I vibe reviewed the dhcrelay source code and dhcrelay6.c explicitly does:
In other words, when building the Relay-Forward dhcrelay6 explicitly populates link-address from the interfaces link-local IPv6 address. That matches exactly what appears in the packet capture.
dispatch.c only records that a non-link-local IPv6 address exists:
The actual GUA/ULA isn't stored, so relay6_pushrelaymsg() has no GUA/ULA available to use for link-address.
I've raised a bug here: https://github.com/opnsense/core/issues/10686
This also looks related to #10623, where Relay-Replies are sent to the wrong VLAN. Different symptom, but likely wrapped up in the same underlying link-address handling.
In any case, I can confirm from packet captures that the endpoint sends a correctly formatted Solicit, OPNsense receives it and generates a Relay-Forward, and that Relay-Forward arrives at the DHCPv6 server successfully over a properly routed, GUA based IPv6 network. The relay and server are on different routed subnets, and the outer IPv6 packet is delivered correctly. I can also rule out the DHCPv6 server itself. A separate Dell switch relays DHCPv6 for other subnets to the same Windows DHCP server successfully. The problem is the embedded DHCPv6 link-address in the OPNsense Relay-Forward. OPNsense uses the client-facing interface's link-local address instead of its GUA, so the DHCP server can't associate the request with the correct scope.
TL;DR: DHCPv6 Solicit is valid → OPNsense receives it → DHCPv6 Relay-Forward is generated → DHCP server receives it → DHCP server itself works with another relay → embedded link-address supplied by OPNsense in the Relay-Forward is wrong.
The relevant OPNsense interface has both:
2406:xxxx:xxxx:b170::1/64
fe80::250:56ff:feaa:bb70
but the Relay-Forward sent to the DHCPv6 server contains:
Link-address: fe80::250:56ff:feaa:bb70
My Windows DHCP server receives the Relay-Forward but can't associate that link-local address with the 2406:xxxx:xxxx:b170::/64 scope, so it sends no reply. For comparison, a Dell switch relaying to the same DHCPv6 server correctly uses its client facing GUA as link-address and Windows immediately returns a Relay-Reply.
I vibe reviewed the dhcrelay source code and dhcrelay6.c explicitly does:
Code Select
dsr->dsr_linkaddr = intf->linklocal;In other words, when building the Relay-Forward dhcrelay6 explicitly populates link-address from the interfaces link-local IPv6 address. That matches exactly what appears in the packet capture.
dispatch.c only records that a non-link-local IPv6 address exists:
Code Select
intf->gipv6 = 1;The actual GUA/ULA isn't stored, so relay6_pushrelaymsg() has no GUA/ULA available to use for link-address.
I've raised a bug here: https://github.com/opnsense/core/issues/10686
This also looks related to #10623, where Relay-Replies are sent to the wrong VLAN. Different symptom, but likely wrapped up in the same underlying link-address handling.
In any case, I can confirm from packet captures that the endpoint sends a correctly formatted Solicit, OPNsense receives it and generates a Relay-Forward, and that Relay-Forward arrives at the DHCPv6 server successfully over a properly routed, GUA based IPv6 network. The relay and server are on different routed subnets, and the outer IPv6 packet is delivered correctly. I can also rule out the DHCPv6 server itself. A separate Dell switch relays DHCPv6 for other subnets to the same Windows DHCP server successfully. The problem is the embedded DHCPv6 link-address in the OPNsense Relay-Forward. OPNsense uses the client-facing interface's link-local address instead of its GUA, so the DHCP server can't associate the request with the correct scope.
TL;DR: DHCPv6 Solicit is valid → OPNsense receives it → DHCPv6 Relay-Forward is generated → DHCP server receives it → DHCP server itself works with another relay → embedded link-address supplied by OPNsense in the Relay-Forward is wrong.
"