IPv6 Subnet behaviour

Setup is RB5009 running 7.21.5 [long term] and connecting via PPPoE.

My ISP delegates Q:Q:Q:e00::/56 and I have been using Q:Q:Q:e00::/64 as my default subnet on LocalBridge. I also have 2 vLANs using subnets Q:Q:Q:e1e::/64 and Q:Q:Q:e20::/64. I am finding that every few days the default subnet is reassigned as Q:Q:Q:e21::/64 or similar and I have been setting it back, because I am using an external connection quality monitor.

I have now duplicated the behaviour by unplugging the external connection and replugging it. So I tried setting the default vLAN subnet to Q:Q:Q:e01::/64 and this seems to stop the subnet being reassigned when I break the external connection. OK, problem probably solved, but just to be more confident about what is happening, is there any reason for the Q:Q:Q:0/64 subnet not to be used? Does it have a special role or is this just a Mikrotik quirk?

Yes, that is a known behavior of 7.21.x-7.22.x, introduced with this change:

Here I wrote about this behavior as well as the workaround for 7.21.x-7.22.x, which is to not use the zero-subnet-id for static assignment:

The issue is resolved in 7.23.x with help of a new parameter, I also have a post about it here:

However, beware of the current issue with /ipv6 nd in 7.23.x. If you decide to install 7.23 or 7.24rc, you'll need to make sure the default /ipv6 nd with the all interface is either disabled or have options like DNS & MTU off / cleared.

Thanks for this. So, my summary, from 7.21 on, setting the subnet to using 0:0:0:0::/64 allows the router to auto assign a subnet and I have just checked, you can assign this more than once for different subnets and get different address ranges. And from 7.23, you can override this behaviour by setting /ipv6 pool-policy to strict. And yes, beware of the /ipv6 nd issue

This behaviour was present since very beginning of IPv6 support in ROS. What changed with 7.21 (mentioned by @CGGXANNX above) is that it's actually possible to set subnet IPv6 address "mask" so that it can seemingly overlap with received prefix.

Example: received prefix is Q:Q:Q:e00::/56 (the last 16 bits, the "00" in the prefix mentioned, are not actually part of prefix, they are simply place holders in HEX-like notation). If you set address=::1:0/64 from-pool=pool_name, resulting address is (and was before) Q:Q:Q:0e00::1:0/64. Using same address assignment on another interface afterwards would yield address Q:Q:Q:0e01::1:0/64 ... etc. (where the exact "subnet" would be pseudo-random).

What changed is that it wasn't possible to set e.g. address=::05:0:0:1:0/64 from-pool=pool_name because address specified had Q4 set ("05") and at the same time prefix from pool had some bits of Q4 set as well ("0e00") and ROS didn't handle that well. IIRC such address assignment did work if received prefix had Q4 all zeroes (e.g. Q:Q:Q::/56) even with same prefix length of /56.
The change in 7.21 was that ROS started to handle the overlapping part of address/prefix so that it's now trying to match bits (bit-wise OR) in both parts (prefix, address assignment) and if it makes sense, it allows resulting full address.

I guess that for backward compatibility, address assignment with Q4 (part overlapping prefix and address) set to 0, is handled by post-7.21 the same way as in pre-7.21 ... meaning to take a random prefix from prefix pool.