odhcpd icon indicating copy to clipboard operation
odhcpd copied to clipboard

Optionally run DHCPv6 server on WAN interface when no IPv6 address Prefix is delegated from ISP

Open Konstantin-Glukhov opened this issue 1 year ago • 18 comments

Add an option to run DHCPv6 server on WAN interface when IPv6 address prefix is not delegated from ISP. Take the ::/64 prefix from the address assigned by DHCPv6 client and use it as base for stateful address assignments for clients DHCPv6 requests coming from the LAN interface (make sure the client DHCPv6 requests are relayed to the WAN interface).

Konstantin-Glukhov avatar Feb 25 '24 09:02 Konstantin-Glukhov

Is it possible to hack together some way to do this?

My use case: having a stable ip address for client devices (i.e. not using SLAAC) in the scenario when my upstream doesn’t support PD. A stable IP address allows me to reliably allow incoming traffic to a particular device.

xrisk avatar Aug 01 '24 21:08 xrisk

Take the ::/64 prefix from the address assigned by DHCPv6 client and use it as base for stateful address assignments for clients DHCPv6 requests

Not sure I understand...if your OpenWRT box has gotten an address via DHCPv6, you have no addresses to assign to clients?

Alphix avatar Sep 20 '25 21:09 Alphix

The WAN dhcpv6 server is marked as master and it does not respond to client requests when the prefix is ::/64 even when the option "Extend 3GPP WAN interface /64 prefix via PD to LAN (RFC 7278)" is enabled. The dhcpv6 server running on the LAN interface does not respond for clients requests either unless I make the LAN interface static and assign ipv6 to the LAN interface manually.

Konstantin-Glukhov avatar Sep 21 '25 00:09 Konstantin-Glukhov

The WAN dhcpv6 server is marked as master and it does not respond to client requests when the prefix is ::/64 even when the option "Extend 3GPP WAN interface /64 prefix via PD to LAN (RFC 7278)" is enabled. The dhcpv6 server running on the LAN interface does not respond for clients requests either unless I make the LAN interface static and assign ipv6 to the LAN interface manually.

I'm still confused. Why would you run a DHCPv6 server on the WAN? In the absence of DHCP-PD, there is no ":/64 prefix from the address assigned by DHCPv6 client". And if you're talking about RFC7278, then a /64 prefix is provided to the WAN side via router advertisement, not DHCP.

The support for RFC7278 is implemented in odhcp6c (OpenWRTs DHCPv6 and RA client), not odhcpd (the server), see here

Anyway, the issue section of this repo isn't very active. I would suggest that you first post to the forum, including logs and configuration files. There's hopefully more people there who can help you figure out if you're experiencing a bug or if your configuration needs to be changed, and to collect the information that would be necessary for a detailed bug report.

Alphix avatar Sep 21 '25 08:09 Alphix

This is not a bug—it's simply that the functionality to serve Global Unicast Addresses (GUAs) is missing.

As I see it, there are two possible ways for DHCPv6 to serve GUAs to clients: either through the WAN interface or via the LAN-side DHCP server. Since GUAs are assigned from the WAN, it would be logical for the WAN side to handle their distribution. However, in OpenWrt, the DHCPv6 server functionality on the WAN side is disabled (grayed out), and only DHCPv6 relay is available.

While it's technically possible to run multiple DHCPv6 servers, OpenWrt has opted to support only relaying on the WAN interface. Given this limitation, the only remaining option is to use the LAN-side DHCPv6 server to manage IPv6 address assignments to clients.

The only method I’ve found that works is to assign a static GUA to the LAN interface. When this is done, odhcpd responds to DHCPv6 client requests as expected. Ideally, this process should be automated—OpenWrt could provide an option for users to request GUA assignment to the LAN interface, instead of requiring manual configuration. However, it's unclear which OpenWrt component would be responsible for implementing such a feature.

Konstantin-Glukhov avatar Sep 21 '25 23:09 Konstantin-Glukhov

As I see it, there are two possible ways for DHCPv6 to serve GUAs to clients: either through the WAN interface or via the LAN-side DHCP server. Since GUAs are assigned from the WAN,

I still don't understand, how does your WAN end up with GUA assignments (plural) in the first place?

Alphix avatar Sep 22 '25 00:09 Alphix

I still don't understand, how does your WAN end up with GUA assignments (plural) in the first place? WAN GUA is assigned via DHCPv6 client (odhcp6c)

Konstantin-Glukhov avatar Sep 22 '25 02:09 Konstantin-Glukhov

I still don't understand, how does your WAN end up with GUA assignments (plural) in the first place? WAN GUA is assigned via DHCPv6 client (odhcp6c)

Then you have no GUAs to assign to downstream clients since the WAN GUA is a ::/128 assignment - i.e. a single IPv6 address.

Alphix avatar Sep 22 '25 07:09 Alphix

It's not the case, I have the whole range of ::/64, my prefix is ::/64.

Konstantin-Glukhov avatar Sep 22 '25 21:09 Konstantin-Glukhov

Ok, just to be clear, I'm asking questions because I'm still confused and I'm trying to understand, in your first message you said there's no DHCPv6-PD from the ISP/upstream router and at the same time that you have a "::/64 prefix from the address assigned by DHCPv6 client" (which can only be assigned via DHCPv6-PD, that is the only protocol in DHCPv6 to actually assign a prefix).

And you say that:

It's not the case, I have the whole range of ::/64, my prefix is ::/64.

So:

  1. How do you know that you have a ::/64? Which steps/commands did you run to determine this and what was their output?
  2. How did your WAN interface get this prefix? Using which protocol/mechanism?
  3. When you "make the LAN interface static and assign ipv6 to the LAN interface manually", as you said above, your LAN clients get an IPv6 address, have you confirmed that that address actually works - i.e. that it is a GUA and that the clients can communicate with a IPv6 server on the Internet using that address?

Alphix avatar Sep 23 '25 09:09 Alphix

I have to admit that my responses are confusing, sorry about that. The reason they are confusing is the fact that I do not quite understand how OpenWrt configures wan6 interface based on ISP RA message.

  1. How do you know that you have a ::/64? Which steps/commands did you run to determine this and what was their output?

The ISP sends the following RA message:

tcpdump -vvvv -n icmp6 and ip6[40] == 134

ICMP6, router advertisement, length 56
 hop limit 64, Flags [other stateful], pref medium, router lifetime 1800s, reachable time 300000ms, retrans timer 10000ms
  source link-address option (1), length 8 (1): <ISP MAC>
  prefix info option (3), length 32 (4): <IPv6 Prefix>::/64, Flags [onlink, auto], valid time 2592000s, pref. time 604800s

but ifstatus wan6 does not show any ipv6-prefix:

"ipv6-address": [
        {
                "address": "<IPv6 Prefix>::<IPv6 Suffix>",
                "mask": 64,
                "preferred": 604543,
                "valid": 2591743
        }
],
"ipv6-prefix": [

],
"ipv6-prefix-assignment": [

],

and ip -6 a shows

wan@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
 inet6 <IPv6 Prefix>::<IPv6 Suffix>/64 scope global dynamic noprefixroute
    valid_lft 2591823sec preferred_lft 604623sec

Even though ipv6-prefix is reported empty by ifstatus wan6 the router IPv6 has mask 64 and all LAN clients get IPv6 GUA based on the ISP RA message. SLAAC addresses get mask 64, though DHCPv6 addresses get mask 128.

  1. How did your WAN interface get this prefix? Using which protocol/mechanism?

DHCPv6 client

  1. When you "make the LAN interface static and assign ipv6 to the LAN interface manually", as you said above, your LAN clients get an IPv6 address, have you confirmed that that address actually works - i.e. that it is a GUA and that the clients can communicate with a IPv6 server on the Internet using that address?

I can access IPv6 only websites with no problems and get 10/10 score at https://test-ipv6.com/ regardless of the LAN client mask length (64 or 128).

Konstantin-Glukhov avatar Sep 24 '25 04:09 Konstantin-Glukhov

I have to admit that my responses are confusing, sorry about that. The reason they are confusing is the fact that I do not quite understand how OpenWrt configures wan6 interface based on ISP RA message.

It doesn't. The "normal" case is that the ISP RA message tells OpenWrt a prefix that's on-link and how the rest of the configuration should proceed. So far, your connection seems pretty standard.

  1. How do you know that you have a ::/64? Which steps/commands did you run to determine this and what was their output?

The ISP sends the following RA message:

tcpdump -vvvv -n icmp6 and ip6[40] == 134

ICMP6, router advertisement, length 56
 hop limit 64, Flags [other stateful], pref medium, router lifetime 1800s, reachable time 300000ms, retrans timer 10000ms
  source link-address option (1), length 8 (1): <ISP MAC>
  prefix info option (3), length 32 (4): <IPv6 Prefix>::/64, Flags [onlink, auto], valid time 2592000s, pref. time 604800s

That looks good. The ISP RA message tells you that:

  1. <IPv6 prefix>::/64 is on on-link (reachable directly from your WAN side without going through any further routers)
  2. That you can use that prefix to perform autoconfiguration (SLAAC) to get an address for your WAN interface
  3. And that you should perform DHCPv6 configuration ([other stateful] )

What it does not tell you is that <IPv6 Prefix>::/64 has been delegated to you.

but ifstatus wan6 does not show any ipv6-prefix:

That is as expected, if we only focus on the RA message you showed above.

and ip -6 a shows

wan@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
 inet6 <IPv6 Prefix>::<IPv6 Suffix>/64 scope global dynamic noprefixroute
    valid_lft 2591823sec preferred_lft 604623sec

This means that the WAN has gotten an IPv6 address via SLAAC, and the /64 means that the prefix is reachable directly via the WAN connection.

Even though ipv6-prefix is reported empty by ifstatus wan6 the router IPv6 has mask 64

Yes, but that's a similar scenario as if your WAN would have an IPv4 address of 192.168.55.2/24 (which simply means that 192.168.55.* is reachable directly).

and all LAN clients get IPv6 GUA based on the ISP RA message. SLAAC addresses get mask 64, though DHCPv6 addresses get mask 128.

That's because of how you setup the LAN side manually though. It might work, for now, but it's not RFC compliant (no DAD, for example) and it has security implications.

  1. How did your WAN interface get this prefix? Using which protocol/mechanism?

DHCPv6 client

Nah, from what you've shown, the WAN interface was configured via RA. And it hasn't been allocated any prefix.

Since you know your way around tcpdump, could you please: a) capture the DHCPv6 traffic on the WAN side as you bring up the remote connection; and b) paste the content of your /etc/config/network configuration

I would expect the wan6 interface in /etc/config/network to look something like this:

config interface 'WAN6'
	option device '@wan'
	option proto 'dhcpv6'
	option sourcefilter '0'
	option reqprefix 'auto'
	option reqaddress 'try'

Alphix avatar Sep 24 '25 09:09 Alphix

/etc/config/network

config interface 'wan6'
        option device 'wan'
        option proto 'dhcpv6'
        option ifaceid '::2'
        option reqaddress 'try'
        option reqprefix 'auto'
        option norelease '1'
        option proxy_ndp '1'

tcpdump -n -i wan '((port 546 or port 547)) or (icmp6[icmp6type] == icmp6-routersolicit or icmp6[icmp6type] == icmp6-routeradvert)'

23:23:10.279572 IP6 (flowlabel 0x8666b, hlim 255, next-header ICMPv6 (58) payload length: 16) fe80::OpenWrt-Address > ff02::2: [icmp6 sum ok] ICMP6, router solicitation, length 16
	  source link-address option (1), length 8 (1): OpenWrt-MAC
	    0x0000:  XXXX XXXX XXXX
23:23:10.500052 IP6 (class 0xb8, hlim 255, next-header ICMPv6 (58) payload length: 56) fe80::ISP-Address > ff02::1: [icmp6 sum ok] ICMP6, router advertisement, length 56
	hop limit 64, Flags [other stateful], pref medium, router lifetime 1800s, reachable time 300000ms, retrans timer 10000ms
	  source link-address option (1), length 8 (1): ISP-MAC
	    0x0000:  XXXX XXXX XXXX
	  prefix info option (3), length 32 (4): GUA::/64, Flags [onlink, auto], valid time 2592000s, pref. time 604800s
	    0x0000:  40c0 0027 8d00 0009 3a80 0000 0000 XXXX
	    0x0010:  XXXX XXXX XXXX 0000 0000 0000 0000
23:23:10.891541 IP6 (flowlabel 0x44c43, hlim 1, next-header UDP (17) payload length: 107) fe80::OpenWrt-Address.546 > ff02::1:2.547: [bad udp cksum 0x3cc3 -> 0x5ed4!] dhcp6 solicit (xid=e33117 (elapsed-time 0) (option-request SIP-servers-domain SIP-servers-address DNS-server DNS-search-list SNTP-servers NTP-server AFTR-Name opt_67 opt_94 opt_95 opt_96 opt_82) (client-ID hwaddr type 1 OpenWrt-MAC) (reconfigure-accept) (Client-FQDN) (IA_NA IAID:1 T1:0 T2:0) (IA_PD IAID:1 T1:0 T2:0))
23:23:10.906180 IP6 (class 0xb8, hlim 64, next-header UDP (17) payload length: 60) fe80::ISP-Address.547 > fe80::OpenWrt-Address.546: [udp sum ok] dhcp6 advertise (xid=e33117 (server-ID hwaddr type 1 ISP-MAC) (client-ID hwaddr type 1 OpenWrt-MAC) (status-code NoPrefixAvail))
23:23:12.453740 IP6 (flowlabel 0x44c43, hlim 1, next-header UDP (17) payload length: 91) fe80::OpenWrt-Address.546 > ff02::1:2.547: [bad udp cksum 0x3cb3 -> 0x57da!] dhcp6 solicit (xid=98487c (elapsed-time 0) (option-request SIP-servers-domain SIP-servers-address DNS-server DNS-search-list SNTP-servers NTP-server AFTR-Name opt_67 opt_94 opt_95 opt_96 opt_82) (client-ID hwaddr type 1 OpenWrt-MAC) (reconfigure-accept) (Client-FQDN) (IA_PD IAID:1 T1:0 T2:0))
23:23:12.469022 IP6 (class 0xb8, hlim 64, next-header UDP (17) payload length: 60) fe80::ISP-Address.547 > fe80::OpenWrt-Address.546: [udp sum ok] dhcp6 advertise (xid=98487c (server-ID hwaddr type 1 ISP-MAC) (client-ID hwaddr type 1 OpenWrt-MAC) (status-code NoPrefixAvail))
23:23:14.469944 IP6 (flowlabel 0x44c43, hlim 1, next-header UDP (17) payload length: 85) fe80::OpenWrt-Address.546 > ff02::1:2.547: [bad udp cksum 0x3cad -> 0xa664!] dhcp6 inf-req (xid=b0783e (elapsed-time 0) (option-request SIP-servers-domain SIP-servers-address DNS-server DNS-search-list SNTP-servers NTP-server AFTR-Name opt_94 opt_95 opt_96 opt_83 lifetime) (client-ID hwaddr type 1 OpenWrt-MAC) (server-ID hwaddr type 1 ISP-MAC) (Client-FQDN))
23:23:14.485049 IP6 (class 0xb8, hlim 64, next-header UDP (17) payload length: 157) fe80::ISP-Address.547 > fe80::OpenWrt-Address.546: [udp sum ok] dhcp6 reply (xid=b0783e (server-ID hwaddr type 1 ISP-MAC) (client-ID hwaddr type 1 OpenWrt-MAC) (DNS-server 2001:a7ff:5f01::a 2001:a7ff:5f01:1::a) (DNS-search-list flets-west.jp. iptvf.jp.) (SNTP-servers 2001:a7ff:102::a 2001:a7ff:102::b 2001:a7ff:102::c))

Konstantin-Glukhov avatar Sep 24 '25 16:09 Konstantin-Glukhov

So the ISP's own RA msg tells your router to get adresses via DHCP, the stateful part in the RA message is the M flag from RFC4861, §4.2:

M              1-bit "Managed address configuration" flag.  When
                     set, it indicates that addresses are available via
                     Dynamic Host Configuration Protocol...

The router then tries DHCPv6, as instructed:

...dhcp6 solicit...(IA_NA IAID:1 T1:0 T2:0) (IA_PD IAID:1 T1:0 T2:0))
...dhcp6 advertise...(status-code NoPrefixAvail))
...dhcp6 solicit...(IA_PD IAID:1 T1:0 T2:0))
...dhcp6 advertise...(status-code NoPrefixAvail))
...dhcp6 inf-req...
...dhcp6 reply...<various info that looks bogus>

So your client first asked for an address (IA_NA) and prefix (IA_PD), but gets a NACK from the remote server (NoPrefixAvail).

It then tries again, but only requests a prefix, and gets another NACK.

Finally it just asks for info, and gets info which looks bogus...

Which ISP is this, if you don't mind me asking? And which kind of connection...? Because the ISPs IPv6 setup seems pretty broken from what I can tell...Does the ISP advertise IPv6 support?

Alphix avatar Sep 25 '25 17:09 Alphix

You did not mention that the RA message has Prefix info (GUI::/64) and Flags: onlink, auto. This allows SLAAC (Stateless Address Autoconfiguration) and this is how OpenWrt gets it IP address. After I provided the tcpdump trace I realized that I don't need to ask for IA_NA and IA_PD via DHCPv6 (they are not available anyway), so I adjusted the wan configuration:

config interface 'wan6'
        option device 'wan'
        option proto 'dhcpv6'
        option verbose '1'
        option ifaceid '::2'
        option reqaddress 'none'
        option reqprefix 'no'
        option proxy_ndp '1'

The ISP is BB.Exicte (https://bb.excite.co.jp/ftth/). From the point of IPv6 specs it is broken :-) but it works, and IPv6 is the only thing it provides. IPv4 is provided via DS-Lite gw.transix.jp tunnel (most of Japan internet IPv6 fiber connections are setup via gw.transix.jp or dgw.xpass.jp) :

config interface 'wan4'
        option proto 'dslite'
        option peeraddr 'gw.transix.jp'
        option encaplimit 'ignore'
        option mtu '1460'

The DNS servers and DNS search path you see at the end of DHCPv6 handshake are needed for gw.transix.jp to be resolved and bring up the tunnel.

I am thinking of bridging wan and br-lan for the setup to be IPv6 compliant, in this case br-lan and wan will be on the same link, I did not figured out yet how to do it. Any ideas?

Konstantin-Glukhov avatar Sep 25 '25 21:09 Konstantin-Glukhov

You did not mention that the RA message has Prefix info (GUI::/64) and Flags: onlink, auto. This allows SLAAC (Stateless Address Autoconfiguration) and this is how OpenWrt gets it IP address.

Yeah, but I already detailed that in an earlier msg https://github.com/openwrt/odhcpd/issues/216#issuecomment-3327405040

After I provided the tcpdump trace I realized that I don't need to ask for IA_NA and IA_PD via DHCPv6 (they are not available anyway), so I adjusted the wan configuration:

config interface 'wan6'
        option device 'wan'
        option proto 'dhcpv6'
        option verbose '1'
        option ifaceid '::2'
        option reqaddress 'none'
        option reqprefix 'no'
        option proxy_ndp '1'

Hm, I don't think proxy_ndp does anything, at least not in odhcpd.

The ISP is BB.Exicte (https://bb.excite.co.jp/ftth/). From the point of IPv6 specs it is broken :-) but it works, and IPv6 is the only thing it provides. IPv4 is provided via DS-Lite gw.transix.jp tunnel (most of Japan internet IPv6 fiber connections are setup via gw.transix.jp or dgw.xpass.jp) :

Hm, I have little experience with Japanese ISPs, but they seem to have "interesting" setups.

My Japanese is non-existant, but after some quick Googling I found this page which mentions DHCPv6 PD.

But then I also came across documents like this one that actually seems to suggest that you might be expected to do something like what you're doing.

Thinking you can't be the first person who wants to setup OpenWrt in Japan, I came across this...it links to scripts that they seem to claim would setup OpenWrt for Japanese end-users.

Specifically this script, which (if I understood correctly) would run this script...some excerpts:

# DHCP LAN
uci set dhcp.lan.ra='relay'
uci set dhcp.lan.dhcpv6='server'
uci set dhcp.lan.ndp='relay'
uci set dhcp.lan.force='1'

# WAN
uci set network.wan.auto='0'

# DHCP WAN6
uci set dhcp.wan6=dhcp
uci set dhcp.wan6.ignore='1'
uci set dhcp.wan6.master='1'
uci set dhcp.wan6.ra='relay'
uci set dhcp.wan6.dhcpv6='relay'
uci set dhcp.wan6.ndp='relay'

Have you tried something along those lines?

Alphix avatar Sep 26 '25 08:09 Alphix

(you might need some firewall rules as well...)

Alphix avatar Sep 26 '25 08:09 Alphix

By the way, the OpenWrt system defaults work without tweaking in Japan.

I tried all possible combinations you mentioned and even made DHCPv6 work on the LAN side. I can do everything I need manually. My request for improvement was to automate manual work.

As of now I see one of two improvements can be made in case when ::/64 prefix delegation is not provided by ISP:

  1. Provide an option to force ::/64 prefix delegation on the WAN side.
  2. Provide an option for static IP configuration on the LAN side to assign GUA from ISP RA message.

P.S. Thanks for looking into the problem and trying to understand it. Unswerving your questions made me more educated on the subject too.

Konstantin-Glukhov avatar Sep 26 '25 09:09 Konstantin-Glukhov