Debugging DHCPv6-PD

I've been working with my ISP for the last couple of days trying to debug IPv6. Until now I have been using a HE tunnel (IPv6 over IPv4) with no issues. Previously with another ISP I had native IPv6 enabled, so I know at least that my end of the configuration worked in the past.

Currently with the modem in gateway mode, the modem is assigned an address and a delegated prefix, but hosts behind the modem are unable to reach any destinations over IPv6 (traceroute timeout). When the modem is switched to bridge mode, OpenWrt receives an IPv6 address via DHCPv6, but no prefix delegation is configured for the wan6 interface. I am able to send/receive data over IPv6 from the OpenWrt router itself, but again, no connectivity from anything behind it, this time due to no prefix being advertised on the local network.

Interestingly, OpenWrt does receive a PD option from upstream but seems to discard it rather than passing it on to my network. With the HE tunnel, prefix delegation and SLAAC addressing works fine.

Below is a dissection of the solicit-advertise-request-reply sequence I observe on the WAN interface (note the IA_PD option that gets ignored by OpenWrt in the advertisement):

09:40:25.907561 02:42:c0:xx:xx:xx > 33:33:00:01:00:02, ethertype IPv6 (0x86dd), length 193: (flowlabel 0xca875, hlim 1, next-header UDP (17) payload length: 139) fe80::42:c0ff:fexx:xx.546 > ff02::1:2.547: [udp sum ok] 
    dhcp6 solicit (xid=bc7f9b (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 0242c0xxxxxx) (reconfigure-accept) (Client-FQDN) (IA_NA IAID:1 T1:0 T2:0) (IA_PD IAID:1 T1:0 T2:0 (IA_PD-prefix ::/64 pltime:0 vltime:0)))
 
09:40:25.925243 00:13:5f:04:9c:d9 > 02:42:c0:xx:xx:xx, ethertype IPv6 (0x86dd), length 250: (class 0xe0, hlim 255, next-header UDP (17) payload length: 196) fe80::213:5fff:fe04:9cd9.547 > fe80::42:c0ff:fexx:xx.546: [udp sum ok]
    dhcp6 advertise (xid=bc7f9b (client-ID hwaddr type 1 0242c0xxxxxx) (server-ID hwaddr/time type 1 time 661197566 005056a7b22b) (IA_NA IAID:1 T1:1000 T2:2000 (IA_ADDR 2a00:7c40:ffcc:xx::xx pltime:3000 vltime:4000)) (DNS-server 2001:4860:4860::8888 2001:4860:4860::8844) (IA_PD IAID:1 T1:1000 T2:2000 (IA_PD-prefix 2a00:7c40:xxxx:xxxx::/64 pltime:3000 vltime:4000 (opt_67))) (Client-FQDN))
 
09:40:27.080339 02:42:c0:xx:xx:xx > 33:33:00:01:00:02, ethertype IPv6 (0x86dd), length 192: (flowlabel 0xca875, hlim 1, next-header UDP (17) payload length: 138) fe80::42:c0ff:fexx:xx.546 > ff02::1:2.547: [udp sum ok]
    dhcp6 request (xid=a740fc (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) (client-ID hwaddr type 1 0242c0xxxxxx) (server-ID hwaddr/time type 1 time 661197566 005056a7b22b) (reconfigure-accept) (Client-FQDN) (IA_NA IAID:1 T1:0 T2:0 (IA_ADDR 2a00:7c40:ffcc:xxxx::xx pltime:3000 vltime:4000)))
 
09:40:27.094075 00:13:5f:04:9c:d9 > 02:42:c0:xx:xx:xx, ethertype IPv6 (0x86dd), length 192: (class 0xe0, hlim 255, next-header UDP (17) payload length: 138) fe80::213:5fff:fe04:9cd9.547 > fe80::42:c0ff:fexx:xx.546: [udp sum ok]
    dhcp6 reply (xid=a740fc (client-ID hwaddr type 1 0242c0xxxxxx) (server-ID hwaddr/time type 1 time 661197566 005056a7b22b) (IA_NA IAID:1 T1:1000 T2:2000 (IA_ADDR 2a00:7c40:ffcc:xx::xx pltime:3000 vltime:4000)) (DNS-server 2001:4860:4860::8888 2001:4860:4860::8844) (Client-FQDN))

Breakdown of option 67 (prefix exclude) which I assume is just saying "don't assign ::1/128" :

            Prefix Exclude
                Option: Prefix Exclude (67)
                Length: 9
                Prefix length: 128
                IPv6 subnet ID: 0000000000000001

I tried requesting prefixes of varying length, setting option forceprefix, and manually setting a prefix based on what I see advertised, to no effect.

Network config:

# uci show network.wan6
network.wan6=interface
network.wan6.ifname='eth1'
network.wan6.proto='dhcpv6'
network.wan6.reqaddress='try'
network.wan6.reqprefix='auto'

Aside from the obvious issue of things still not working when only using ISP equipment set to gateway mode (modem + router), any insight as to what's missing here is appreciated.

Apparently OpenWrt is sending a prefix-length hint of 64 in the DHCPv6 solicit message.

Please try to make OpenWrt ask for a shorter prefix (/56 or /60) while the modem is in bridge mode, and post the new packet capture / dissection.

Thank you @mpa for your reply.

Unfortunately, setting reqprefix to any value (including auto) always results in a /64 prefix being advertised. This was confirmed by my ISP as the intended behavior; they do not offer prefixes of any other size.

If your ISP only gives you one /64 prefix, you might need to use the relay mode in OpenWrt.

See relay example in wiki.
https://openwrt.org/docs/guide-user/network/ipv6/start#router_advertisement_dhcpv6

Or

Thanks @hnyman. I have my network config as follows:

# /etc/config/network
config interfcae 'lan'
        option ifname 'eth0'
        option type 'bridge'
        ...

config interface 'wan6'             
        option ifname 'eth1'          
        option proto 'dhcpv6'   
# /etc/config/dhcp
config dhcp 'lan'                                 
        option interface 'lan'                       
        option ndp 'relay'          
        option ra 'relay'              
        option dhcpv6 'relay'      

config dhcp 'wan'                   
        option interface 'wan6'                   
        option dhcpv6 'relay'              
        option ra 'relay'              
        option ndp 'relay'                  
        option master '1'  

I also have the HE-tunnel configuration in /etc/config/network working properly, so I know prefix delegation works, at least for that interface. I haven't tried deleting this interface (only bringing it down), assuming it won't interfere with the prefix delegation from WAN.

You are being assigned a /64 prefix, which is rather cheap on behalf of your provider, but there is no need for relay. This can be assigned to just one interface.
What is the full output of uci export network; ifstatus wan6

Thanks @trendy, yes "rather cheap" is right :sweat_smile:

Don't mind all the extra GRE tunnel and extra stuff here:

uci export network
package network

config globals 'globals'
        option ula_prefix 'x:x:x::/48'

config interface 'loopback'
        option ifname 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config interface 'lan'
        option type 'bridge'
        option proto 'static'
        option ipaddr '192.168.16.2'
        option netmask '255.255.255.0'
        option ip6assign '64'
        option igmp_snooping '1'
        option stp '1'
        option ifname 'eth0 @trunk.1'
        option ip6ifaceid 'eui64'

config interface 'cam'
        option type 'bridge'
        option proto 'static'
        option ipaddr '192.168.11.2'
        option netmask '255.255.255.0'
        option igmp_snooping '1'
        option stp '1'
        option ifname 'eth0.11 @trunk.11'

config interface 'wan'
        option ifname 'eth1'
        option proto 'dhcp'

config interface 'wan6'
        option ifname 'eth1'
        option proto 'dhcpv6'

# used for backup
config interface 'wan_tether'
        option ifname 'usb0'
        option proto 'dhcp'

config interface 'henet'
        option proto '6in4'
        option peeraddr '216.66.88.98'
        option ip6addr 'xxxx:xxxx:xxxx:xxxx::/64'
        option tunnelid 'xxxx'
        option username 'xxxx'
        option password 'xxxx'
        list ip6prefix 'xxxx:xxxx:xxxx:xxxx::/64'
        option defaultroute '0'

config interface 'gre'
        option proto 'gretap'
        option ipaddr '10.99.0.2'
        option peeraddr '10.99.0.22'
        option tunlink 'wtun'
        option network 'trunk'
        option df '0'
        option mtu '1500'

config interface 'trunk'
        option type 'bridge'
        option proto 'none'
        option auto '1'
        option bridge_empty '1'
        option delegate '0'
        option igmp_snooping '1'
        option stp '1'

config interface 'wtun'
        option proto 'static'
        option ipaddr '10.99.0.2'
        option netmask '255.255.255.0'
        option delegate '0'
        option mtu '2048'

No prefix on wan6:

ifstatus wan6
{
  "up": true,
  "pending": false,
  "available": true,
  "autostart": true,
  "dynamic": false,
  "uptime": 5632,
  "l3_device": "eth1",
  "proto": "dhcpv6",
  "device": "eth1",
  "metric": 0,
  "dns_metric": 0,
  "delegation": true,
  "ipv4-address": [],
  "ipv6-address": [
    {
      "address": "2a00:7c40:ffcc:xxxx::xx",
      "mask": 128,
      "preferred": 2368,
      "valid": 3368
    }
  ],
  "ipv6-prefix": [],
  "ipv6-prefix-assignment": [],
  "route": [
    {
      "target": "::",
      "mask": 0,
      "nexthop": "fe80::213:5fff:xxxx:xxxx",
      "metric": 512,
      "valid": 1794,
      "source": "2a00:7c40:ffcc:xxxx::xx/128"
    }
  ],
  "dns-server": [
    "2001:4860:4860::8888",
    "2001:4860:4860::8844"
  ],
  "dns-search": [],
  "neighbors": [],
  "inactive": {
    "ipv4-address": [],
    "ipv6-address": [],
    "route": [],
    "dns-server": [],
    "dns-search": [],
    "neighbors": []
  },
  "data": {
    "passthru": "001700202001486048600000000000000000888820014860486000000000000000008844"
  }
}

Compare with ifstatus henet for the HE tunnel:

ifstatus henet
{
  "up": true,
  "pending": false,
  "available": true,
  "autostart": true,
  "dynamic": false,
  "uptime": 8618,
  "l3_device": "6in4-henet",
  "proto": "6in4",
  "updated": [
    "addresses",
    "routes",
    "prefixes"
  ],
  "metric": 0,
  "dns_metric": 0,
  "delegation": true,
  "ipv4-address": [],
  "ipv6-address": [
    {
      "address": "2001:470:1f1c:xxxx::2",
      "mask": 64
    }
  ],
  "ipv6-prefix": [
    {
      "address": "2001:470:1f1d:xxxx::",
      "mask": 64,
      "class": "henet",
      "assigned": {
        "lan": {
          "address": "2001:470:1f1d:xxxx::",
          "mask": 64
        }
      }
    }
  ],
  "ipv6-prefix-assignment": [],
  "route": [],
  "dns-server": [],
  "dns-search": [],
  "neighbors": [],
  "inactive": {
    "ipv4-address": [],
    "ipv6-address": [],
    "route": [
      {
        "target": "::",
        "mask": 0,
        "nexthop": "::",
        "source": "2001:470:1f1c:xxxx::2/64"
      },
      {
        "target": "::",
        "mask": 0,
        "nexthop": "::",
        "source": "2001:470:1f1d:xxxx::/64"
      }
    ],
    "dns-server": [],
    "dns-search": [],
    "neighbors": []
  },
  "data": {}
}

You can get a /48 subnet by clicking on the request button when logged in to tunnelbroker.net .
I use the /48 when stacking routers in the house, to test IPV6 prefix delegation. I get 9/10 however, from test-ipv6.com .

Is the address of wan6 within the same /64 that is delegated?

@trendy no, the IA_NA and IA_PD address ranges are non-overlapping.

A thought: Does OpenWrt do any sort of "check" to see if the advertised prefix is valid before advertising it on the LAN?

I don't have any visibility as to what's going on at the ISP side, but since I have no connectivity even in gateway mode with my computer directly connected to the ISP equipment (no OpenWrt), I believe that PD is misconfigured on their end of the link. I'm also not familiar with how ISPs set up their routing tables, but could it be that they are simply handing out a prefix without updating the appropriate routes on their end?

I also see that each subsequent solicitation request increments the PD prefix by 1. I started at 0 and I'm up to 45 (hexadecimal), so that seems pretty bogus.

At a first glance I don't see anything else wrong here, but the mistake might be hidden in the details of the prefixes that the router gets on wan6 and the delegated.
Given the infrastructure of the ISP, I tend to believe the problem is from their side. You can masquerade the ipv6 prefixes in a consistent way so that we get to see the whole picture and you don't reveal too much.

1 Like

I did some reading and some more debugging with a different DHCPv6 client (dhcpcd5) on another machine. I got prefix delegation working, which led to me noticing that odhcp6c doesn't bother to request a prefix!

tcpdump (odhcp6c)
10:47:38.533788 02:42:c0:xx:xx:xx > 33:33:00:01:00:02, ethertype IPv6 (0x86dd), length 164: (flowlabel 0xba444, hlim 1, next-header UDP (17) payload length: 110) fe80::42:c0ff:fexx:xxx.546 > ff02::1:2.547: [udp sum ok] 
    dhcp6 solicit (xid=13b02f (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 0242c0xxxxxx) (reconfigure-accept) (Client-FQDN) (IA_NA IAID:1 T1:0 T2:0) (IA_PD IAID:1 T1:0 T2:0))

10:47:38.604784 00:13:5f:04:9c:d9 > 02:42:c0:xx:xx:xx, ethertype IPv6 (0x86dd), length 250: (class 0xe0, hlim 255, next-header UDP (17) payload length: 196) fe80::213:5fff:fe04:9cd9.547 > fe80::42:c0ff:fexx:xxx.546: [udp sum ok] 
    dhcp6 advertise (xid=13b02f (client-ID hwaddr type 1 0242c0xxxxxx) (server-ID hwaddr/time type 1 time 661197566 005056a7b22b) (IA_NA IAID:1 T1:1000 T2:2000 (IA_ADDR 2a00:7c40:yyyy:yy::yy pltime:3000 vltime:4000)) (DNS-server 2001:4860:4860::8888 2001:4860:4860::8844) (IA_PD IAID:1 T1:1000 T2:2000 (IA_PD-prefix 2a00:7c40:xxxx:xx::/64 pltime:3000 vltime:4000 (opt_67))) (Client-FQDN))

10:47:39.740903 02:42:c0:xx:xx:xx > 33:33:00:01:00:02, ethertype IPv6 (0x86dd), length 192: (flowlabel 0xba444, hlim 1, next-header UDP (17) payload length: 138) fe80::42:c0ff:fexx:xxx.546 > ff02::1:2.547: [udp sum ok] 
    dhcp6 request (xid=f78819 (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) (client-ID hwaddr type 1 0242c0xxxxxx) (server-ID hwaddr/time type 1 time 661197566 005056a7b22b) (reconfigure-accept) (Client-FQDN) (IA_NA IAID:1 T1:0 T2:0 (IA_ADDR 2a00:7c40:yyyy:yy::yy pltime:3000 vltime:4000)))

10:47:39.762081 00:13:5f:04:9c:d9 > 02:42:c0:xx:xx:xx, ethertype IPv6 (0x86dd), length 192: (class 0xe0, hlim 255, next-header UDP (17) payload length: 138) fe80::213:5fff:fe04:9cd9.547 > fe80::42:c0ff:fexx:xxx.546: [udp sum ok] 
    dhcp6 reply (xid=f78819 (client-ID hwaddr type 1 0242c0xxxxxx) (server-ID hwaddr/time type 1 time 661197566 005056a7b22b) (IA_NA IAID:1 T1:1000 T2:2000 (IA_ADDR 2a00:7c40:yyyy:yy::yy pltime:3000 vltime:4000)) (DNS-server 2001:4860:4860::8888 2001:4860:4860::8844) (Client-FQDN))

In the packet capture above, odhcp6c is sending a solicitation with IAID:1 for both the NA and PD. This appears to be valid per RFC8415 (the latest official DHCPv6 spec), however the text of the obsoleted RFC suggests that this is invalid. The advertisement that comes back does contain a prefix, but it seems to be ignored by odhcp6c in the subsequent request.

By requesting the IA_NA with IAID:1 and IA_PD with IAID:2, the server replies with both:

tcpdump (dhcpcd5)
10:30:59.920010 IP6 (flowlabel 0x9d36d, hlim 1, next-header UDP (17) payload length: 158) fe80::96c6:91ff:fe19:d715.546 > ff02::1:2.547: [udp sum ok] 
    dhcp6 solicit (xid=826ef5 (client-ID hwaddr/time type 1 time 605303213 3052cbxxxxxx) (elapsed-time 0) (vendor-class) (rapid-commit) (IA_NA IAID:1 T1:0 T2:0) (IA_PD IAID:2 T1:0 T2:0) (reconfigure-accept) (option-request DNS-server DNS-search-list Client-FQDN opt_82 opt_83))

10:30:59.958068 IP6 (class 0xe0, hlim 255, next-header UDP (17) payload length: 173) fe80::213:5fff:fe04:9cd9.547 > fe80::96c6:91ff:fe19:d715.546: [udp sum ok] 
    dhcp6 advertise (xid=826ef5 (client-ID hwaddr/time type 1 time 605303213 3052cbxxxxxx) (server-ID hwaddr/time type 1 time 661197566 005056a7b22b) (IA_NA IAID:1 T1:1000 T2:2000 (IA_ADDR 2a00:7c40:yyyy:yy::yy pltime:3000 vltime:4000)) (DNS-server 2001:4860:4860::8888 2001:4860:4860::8844) (IA_PD IAID:2 T1:1000 T2:2000 (IA_PD-prefix 2a00:7c40:xxxx:xx::/64 pltime:3000 vltime:4000)))

10:30:59.958586 IP6 (flowlabel 0x9d36d, hlim 1, next-header UDP (17) payload length: 229) fe80::96c6:91ff:fe19:d715.546 > ff02::1:2.547: [udp sum ok] 
    dhcp6 request (xid=28849a (client-ID hwaddr/time type 1 time 605303213 3052cbxxxxxx) (server-ID hwaddr/time type 1 time 661197566 005056a7b22b) (elapsed-time 0) (vendor-class) (IA_NA IAID:1 T1:0 T2:0 (IA_ADDR 2a00:7c40:yyyy:yy::yy pltime:3000 vltime:4000)) (IA_PD IAID:2 T1:0 T2:0 (IA_PD-prefix 2a00:7c40:xxxx:xx::/64 pltime:3000 vltime:4000)) (reconfigure-accept) (option-request DNS-server DNS-search-list Client-FQDN opt_82 opt_83))

10:30:59.977262 IP6 (class 0xe0, hlim 255, next-header UDP (17) payload length: 173) fe80::213:5fff:fe04:9cd9.547 > fe80::96c6:91ff:fe19:d715.546: [udp sum ok] 
    dhcp6 reply (xid=28849a (client-ID hwaddr/time type 1 time 605303213 3052cbxxxxxx) (server-ID hwaddr/time type 1 time 661197566 005056a7b22b) (IA_NA IAID:1 T1:1000 T2:2000 (IA_ADDR 2a00:7c40:yyyy:yy::yy pltime:3000 vltime:4000)) (DNS-server 2001:4860:4860::8888 2001:4860:4860::8844) (IA_PD IAID:2 T1:1000 T2:2000 (IA_PD-prefix 2a00:7c40:xxxx:xx::/64 pltime:3000 vltime:4000)))

Configuring dhcpcd5 to request both the IA_NA and IA_PD with IAID:1 results in exactly the same behavior as observed with odhcp6c (no PD in request); in fact it even complains with the following warning:

Cannot mix IA for the same IAID 

I am running the latest available version of odhcp6c as of the time of writing:

root@openwrt:~# opkg info odhcp6c
Package: odhcp6c
Version: 2021-01-09-64e1b4e7-16
Depends: libc, libubox20191228
Status: install user installed
Section: net
Architecture: x86_64
Size: 27177
Filename: odhcp6c_2021-01-09-64e1b4e7-16_x86_64.ipk
Description: Embedded DHCPv6-client for OpenWrt
Installed-Time: 1611554546

So, the question is: how do I configure odhcp6c to request the non-temporary address and delegated prefix with different IAIDs?

Working dhcpcd5 config file for reference:

dhcpcd.conf
# IPv6 debug
allowinterfaces eth0 br0
duid
option rapid_commit
option domain_name_servers, domain_name, domain_search, host_name
require dhcp_server_identifier
slaac private
ipv6only
debug
release
noipv6rs

interface eth0
        ipv6rs
        ia_na 1
        ia_pd 2/::/0 br0/0/64

It is not a problem in my case. Both IA_NA and IA_PD are 1 in the solicit, dhcp6 server replies with only IA_PD and only IA_PD is used in the request.
You can do
uci set network.wan6.reqaddress='none' ; uci commit network; ifup wan6 to avoid requesting the address, you should already have one from the RA and it is actually not needed.

Thanks, I did not think to try that.
The request still goes out without asking for a prefix:

14:33:39.519614 IP6 (flowlabel 0xba444, hlim 1, next-header UDP (17) payload length: 94) fe80::42:c0ff:fexx:xxx.546 > ff02::1:2.547: [udp sum ok] 
    dhcp6 solicit (xid=e81231 (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 0242c0xxxxxx) (reconfigure-accept) (Client-FQDN) (IA_PD IAID:1 T1:0 T2:0))

14:33:39.533493 IP6 (class 0xe0, hlim 255, next-header UDP (17) payload length: 152) fe80::213:5fff:fe04:9cd9.547 > fe80::42:c0ff:fexx:xxx.546: [udp sum ok] 
    dhcp6 advertise (xid=e81231 (client-ID hwaddr type 1 0242c0xxxxxx) (server-ID hwaddr/time type 1 time 661197566 005056a7b22b) (DNS-server 2001:4860:4860::8888 2001:4860:4860::8844) (IA_PD IAID:1 T1:1000 T2:2000 (IA_PD-prefix 2a00:7c40:xxxx::/64 pltime:3000 vltime:4000 (opt_67))) (Client-FQDN))

14:33:41.289936 IP6 (flowlabel 0xba444, hlim 1, next-header UDP (17) payload length: 92) fe80::42:c0ff:fexx:xxx.546 > ff02::1:2.547: [udp sum ok] 
    dhcp6 inf-req (xid=ff2f90 (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 0242c0xxxxxx) (server-ID hwaddr/time type 1 time 661197566 005056a7b22b) (Client-FQDN))

14:33:41.306441 IP6 (class 0xe0, hlim 255, next-header UDP (17) payload length: 80) fe80::213:5fff:fe04:9cd9.547 > fe80::42:c0ff:fexx:xxx.546: [udp sum ok] 
    dhcp6 reply (xid=ff2f90 (client-ID hwaddr type 1 0242c0xxxxxx) (server-ID hwaddr/time type 1 time 661197566 005056a7b22b) (DNS-server 2001:4860:4860::8888 2001:4860:4860::8844))

Per your second point, RAs on WAN do not contain any addresses.

16:54:42.736439 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::213:5fff:fe04:9cd9 > ff02::1: [icmp6 sum ok] ICMP6, router advertisement, length 32
        hop limit 64, Flags [managed, other stateful], pref medium, router lifetime 1800s, reachable time 0ms, retrans timer 5000ms
          source link-address option (1), length 8 (1): 00:13:5f:04:9c:d9
          mtu option (5), length 8 (1):  1500

Are you sure? I can see the IA_PD in the solicit.
And I don't think after the reply you should send inf-req.

Yes, the solicit contains IA_PD as well as the advertisement, but then the request (3rd packet) drops the IA_PD.
This is the behavior of odhcp6c with option reqaddress 'none' as you suggested. Changing it back to try restores the type to request instead of information request.

This is not what I see in my case:

root@magiatiko / > tcpdump -i pppoe-wan -evn icmp6 or udp port 547
tcpdump: listening on pppoe-wan, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes
17:06:11.628890 Out ethertype IPv6 (0x86dd), length 189: (flowlabel 0x0f95c, hlim 1, next-header UDP (17) payload length: 133) fe80::6986:3909:5488:de44.546 > ff02::1:2.547: [udp sum ok] dhcp6 release (xid=ecc22a (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) (client-ID hwaddr type 1 001e101f0000) (server-ID hwaddr type 1 6c3b6bee0d46) (Client-FQDN) (IA_PD IAID:1 T1:0 T2:0 (IA_PD-prefix 2222:333:4444:7500::/56 pltime:0 vltime:0)))
17:06:11.655505 Out ethertype IPv6 (0x86dd), length 64: (flowlabel 0xbf69b, hlim 255, next-header ICMPv6 (58) payload length: 8) fe80::6986:3909:5488:de44 > ff02::2: [icmp6 sum ok] ICMP6, router solicitation, length 8
17:06:11.683782  In ethertype IPv6 (0x86dd), length 144: (class 0xc0, hlim 255, next-header ICMPv6 (58) payload length: 88) fe80::10c > ff02::1: [icmp6 sum ok] ICMP6, router advertisement, length 88
	hop limit 64, Flags [managed], pref medium, router lifetime 1800s, reachable time 0ms, retrans timer 0ms
	  rdnss option (25), length 40 (5):  lifetime 900s, addr: 2001:4860:4860::8844 addr: 2001:4860:4860::8888
	  prefix info option (3), length 32 (4): 2222:3333:4444:75d3::/64, Flags [onlink, auto], valid time 2592000s, pref. time 604800s
17:06:11.683782  In ethertype IPv6 (0x86dd), length 118: (hlim 64, next-header UDP (17) payload length: 62) fe80::10c.547 > fe80::6986:3909:5488:de44.546: [udp sum ok] dhcp6 reply (xid=ecc22a (client-ID hwaddr type 1 001e101f0000) (server-ID hwaddr type 1 6c3b6bee0d46) (status-code Success) (IA_PD IAID:1 T1:0 T2:0))
17:06:11.712423 Out ethertype IPv6 (0x86dd), length 152: (flowlabel 0x0f95c, hlim 1, next-header UDP (17) payload length: 96) fe80::6986:3909:5488:de44.546 > ff02::1:2.547: [udp sum ok] dhcp6 solicit (xid=580768 (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 001e101f0000) (reconfigure-accept) (Client-FQDN) (IA_PD IAID:1 T1:0 T2:0))
17:06:11.729891  In ethertype IPv6 (0x86dd), length 182: (hlim 64, next-header UDP (17) payload length: 126) fe80::10c.547 > fe80::6986:3909:5488:de44.546: [udp sum ok] dhcp6 advertise (xid=580768 (client-ID hwaddr type 1 001e101f0000) (server-ID hwaddr type 1 6c3b6bee0d46) (preference 255) (DNS-server 2001:4860:4860::8888 2001:4860:4860::8844) (IA_PD IAID:1 T1:450 T2:720 (IA_PD-prefix 2222:333:4444:7500::/56 pltime:810 vltime:900)))
17:06:12.123708 Out ethertype IPv6 (0x86dd), length 193: (flowlabel 0x0f95c, hlim 1, next-header UDP (17) payload length: 137) fe80::6986:3909:5488:de44.546 > ff02::1:2.547: [udp sum ok] dhcp6 request (xid=a8d141 (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) (client-ID hwaddr type 1 001e101f0000) (server-ID hwaddr type 1 6c3b6bee0d46) (reconfigure-accept) (Client-FQDN) (IA_PD IAID:1 T1:0 T2:0 (IA_PD-prefix 2222:333:4444:7500::/56 pltime:810 vltime:900)))
17:06:12.129526  In ethertype IPv6 (0x86dd), length 177: (hlim 64, next-header UDP (17) payload length: 121) fe80::10c.547 > fe80::6986:3909:5488:de44.546: [udp sum ok] dhcp6 reply (xid=a8d141 (client-ID hwaddr type 1 001e101f0000) (server-ID hwaddr type 1 6c3b6bee0d46) (DNS-server 2001:4860:4860::8888 2001:4860:4860::8844) (IA_PD IAID:1 T1:450 T2:720 (IA_PD-prefix 2222:333:4444:7500::/56 pltime:810 vltime:900)))

TL;DR I am asking only for PD, I get one and the 3rd packet is request.
Make sure you do a ifup wan6 to restart the interface correctly.
My config for reference:

network.wan6=interface
network.wan6.proto='dhcpv6'
network.wan6.peerdns='0'
network.wan6.metric='20'
network.wan6.macaddr='00:1e:10:1f:00:00'
network.wan6.clientid='00030001001e101f0000'
network.wan6.reqprefix='auto'
network.wan6.ifname='@wan'
network.wan6.reqaddress='none'

Also look at the logs: logread -e odhcp6c

Interesting, thank you for sharing.
So it seems that odhcp6c will only ask for a non-temporary address if it did not receive a prefix through router advertisement.

What I don't understand is why odhcp6c sends out a request without asking for a prefix even after an advertisement comes back from the server advertising a prefix, even after setting forceprefix '1'. I also tried setting macaddr and clientid as you did to clone my ISP equipment with no change.

Very strange indeed.

Cc @dedeckeh
Any observations from you?