Incorrect/invalid IPv6 PD-based assignments to multiple downstream LANs

I’ve been running IPv6 on my RB5009 running RouterOS 7.20.5 as my home router, downstream from an Xfinity residential service. The carrier assigns me a /60 via PD, shown below (modifying actual v6 prefix for privacy):

[admin@Home-Edge1] > /ipv6/dhcp-client/export
/ipv6 dhcp-client
add interface=ether1 pool-name=pool0 prefix-hint=::/60 request=address,prefix use-peer-dns=no
[admin@Home-Edge1] >

[admin@Home-Edge1] > /ipv6/dhcp-client/print
Columns: INTERFACE, STATUS, REQUEST, PREFIX
INTERFACE  STATUS  REQUEST  PREFIX
0 ether1     bound   address  2001:601:7890:abc0::/60, 3d10h3m39s
prefix
[admin@Home-Edge1] >

My first interface, MAIN_VLAN_1, gets a correct /64 allocated downstream, but I’m running into trouble adding ipv6 for my two new vlan interfaces, GUEST_VLAN_10 and IOT_VLAN_20. I'm assigning ::1 from pool0 to the two additional downstream vlan interefaces, but when I start with ::1, they get changed to ::a000 and ::b000 as /64s in the configuration (seemingly incrementing every time I test this), putting them in the same subnet effectively:

[snohomish@Snohomish-Edge1] > /ipv6/address/add address=::1 from-pool=pool0 interface=GUEST_VLAN_10
[snohomish@Snohomish-Edge1] > /ipv6/address/add address=::1 from-pool=pool0 interface=IOT_VLAN_20
[snohomish@Snohomish-Edge1] > /ipv6/address/export
/ipv6 address
add address=::1 from-pool=pool0 interface=MAIN_VLAN_1
add address=fd00:effe:3204::1 interface=MAIN_VLAN_1
add address=fd00:effe:3204:a::1 interface=GUEST_VLAN_10
add address=fd00:effe:3204:14::1 interface=IOT_VLAN_20
add address=::a000:0:0:1 from-pool=pool0 interface=GUEST_VLAN_10
add address=::b000:0:0:1 from-pool=pool0 interface=IOT_VLAN_20
[snohomish@Snohomish-Edge1] >

Note that I’m also assigning ULA subnets to each, but I don’t believe that’s relevant here. LMK if I’m wrong on that.

What I'd expect to see is the three vlans to be numbered 2001:601:a583:44c0::1/64, 2001:601:a583:44c1::1/64, and 2001:601:a583:44c2::1/64 (the last nibble of the /64 denoting the disaggregation from the /60). However, here’s what I see instead (filtering out link-local and ULA entries):

[admin@Home-Edge1] > /ipv6/address/print
Flags: D - DYNAMIC; G - GLOBAL, L - LINK-LOCAL
Columns: ADDRESS, FROM-POOL, INTERFACE, ADVERTISE, VALID

ADDRESS                                     FROM-POOL  INTERFACE      ADVERTISE  VALID

0 D  ::1/128                                                lo             no
3  G 2001:601:7890:abc0::1/64                    pool0      MAIN_VLAN_1    yes
12  G 2001:601:7890:abc0:a000::1/64               pool0      GUEST_VLAN_10  yes
13  G 2001:601:7890:abc0:b000::1/64               pool0      IOT_VLAN_20    yes
[admin@Home-Edge1] >

Which means the three downstream LANs addresses out of the same /64, which should not be the case. The routing table shows this more clearly (again, filtering out link-local and ULA):

[admin@Home-Edge1] > /ipv6/route/print
Flags: D - DYNAMIC; I - INACTIVE, A - ACTIVE; c - CONNECT, d - DHCP, g - SLAAC; + - ECMP
Columns: DST-ADDRESS, GATEWAY, ROUTING-TABLE, DISTANCE
DST-ADDRESS               GATEWAY                        ROUTING-TABLE  DISTANCE
DAg  ::/0                      fe80::21c:73ff:fe00:99%ether1  main                  1
DAc  ::1/128                   lo                             main                  0
DAd  2001:601:7890:abc0::/60                                  main                  1
DAc+ 2001:601:7890:abc0::/64   MAIN_VLAN_1                    main                  0
DAc+ 2001:601:7890:abc0::/64   GUEST_VLAN_10                  main                  0
DAc+ 2001:601:7890:abc0::/64   IOT_VLAN_20                    main                  0
[admin@Home-Edge1] >

Even odder, the used pool statistics shows /68s, not /64s! SLAAC would not like this at all.

[admin@Home-Edge1] > /ipv6/pool/used/print
Columns: POOL, PREFIX, OWNER, INFO
POOL   PREFIX                        OWNER    INFO
pool0  2001:601:7890:abc0::/68       Address  MAIN_VLAN_1
pool0  2001:601:7890:abc0:a000::/68  Address  GUEST_VLAN_10
pool0  2001:601:7890:abc0:b000::/68  Address  IOT_VLAN_20
[admin@Home-Edge1] >

I don’t know if I’ve got a config mistake (should I not be using ::1 for all three interfaces?) or if we’re looking at a bug (the /68s under /ipv6/pool/used makes me suspicious here), but the upshot is that I’ve only got one useful IPv6 LAN in my network. Would love some advice or investigation :slight_smile:

Issue this command: /ipv6/dhcp-client/print detail

and check that the pool-prefix-length is 64, not 68.

You can configure that in the IPv6 DHCP client.

You might have a bogus value for pool-prefix-length of the DHCPv6 client. Maybe pool-prefix-length could not be correctly upgraded from older versions (the data type used to be a string). Please see this behavior of older versions, that has now been edited out from the documentation:

Page Comparison - DHCP (v.94 vs v.95) - RouterOS - MikroTik Documentation

Your pool-prefix-length might have a bogus value that is < 60 (60 is the prefix length given out by your ISP) which causes your RouterOS version to adjust the prefix length of the pool to 60 + 8 = 68.

You should be able to fix the issue by explicitly entering 64 in the field (or maybe set to 62, save, then set to 64 and save again to be sure that the changes are written). If the issue persists, try to disable then re-enable the DHCPv6 client entry.

You can also upgrade to 7.22rc, which should no longer have the + 8 auto-adjustment behavior and refuses to bind the prefix if the pool-prefix-length is less than the prefix length from ISP.

Also, from 7.21 you can also explicitly specify the subnet-id when assigning addresses from IPv6 pool.

Aaaand… disabling/then re-enabling the DHCPv6 client did the trick! Thanks again for the pointers.

[admin@Home-Edge1] /ipv6/pool/used> /ipv6/address/print
Flags: D - DYNAMIC; G - GLOBAL, L - LINK-LOCAL
Columns: ADDRESS, FROM-POOL, INTERFACE, ADVERTISE, VALID

ADDRESS                                     FROM-POOL  INTERFACE      ADVERTISE  VALID

0 D  ::1/128                                                lo             no
3  G 2601:601:7890:abc0::1/64                    pool0      MAIN_VLAN_1    yes
12  G 2601:601:7890:abc1::1/64                   pool0      GUEST_VLAN_10  yes
13  G 2601:601:7890:abc2::1/64                   pool0      IOT_VLAN_20    yes
14 DG 2001:558:1234:5678:90ab:cdef:1234:5678/128             ether1         no

[admin@Home-Edge1] /ipv6/pool/used> /ipv6/route/print
Flags: D - DYNAMIC; I - INACTIVE, A - ACTIVE; c - CONNECT, d - DHCP, g - SLAAC
Columns: DST-ADDRESS, GATEWAY, ROUTING-TABLE, DISTANCE
DST-ADDRESS                              GATEWAY                        ROUTING-TABLE  DISTANCE
DAg ::/0                                     fe80::21c:73ff:fe00:99%ether1  main                  1
DAc ::1/128                                  lo                             main                  0
DAd 2601:601:7890:abc0::/60                                                 main                  1
DAc 2601:601:7890:abc0::/64                  MAIN_VLAN_1                    main                  0
DAc 2601:601:7890:abc1::/64                  GUEST_VLAN_10                  main                  0
DAc 2601:601:7890:abc2::/64                  IOT_VLAN_20                    main                  0
[admin@Home-Edge1] >

Output of that command (with specific addresses masked): It was 64 by default:

[admin@Home-Edge1] > /ipv6/dhcp-client/print detail
Flags: D - dynamic; X - disabled, I - invalid
0 interface=ether1 status=bound duid="0x0000aaaabbbbccccddddeeee" dhcp-server-v6=2001:558:7890:abcd::10 request=address,prefix accept-prefix-without-address=yes
add-default-route=no default-route-tables=default check-gateway=none use-peer-dns=no validate-server-duid=yes allow-reconfigure=no dhcp-options="" pool-name="pool0"
pool-prefix-length=64 prefix-hint=::/60 prefix-address-lists="" dhcp-options="" prefix=2601:601:7890abc0::/60, 3d6h17m49s

I set it explicitly (changed it to 60 first, then back to 64 to make sure it wasn’t a stale default), and got the same output.

I’ll try 7.21 and see if setting the subnet-id is the fix for me. Thanks @CGGXANNX for that pointer :slight_smile: