Changing ipv6 prefix

EDIT: Note that the script code in this post was last updated on 23 February 2023

Sorry for the thread bump, but this seemed the best place to put this.

Inspired by previous postings here, I have taken a swing at implementing RFC6204/RFC7084/RFC9096 via scripting. But this time, in such a way that you can still use v6 prefix pools. You should be able to drop this script in place on a router otherwise configured as you would expect (DHCPv6 client obtaining delegated prefix from ISP, and then assigning longer prefixes out of the dynamic pool that’s generated to various interfaces), and it will “just work”. In my limited testing so far, it seems to be pretty robust. Note, though, that so far I have only tested under 6.49.x. Feedback appreciated if you give it a try.

I almost despaired at being able to get this to work, since the dynamic pool created by the DHCPv6 client (and thus the Used Prefixes assigned from that pool) is instantly deleted prior to the on-lease-change script running, so it was impossible to grab a list of the used prefixes that needed to be invalidated from ‘/ipv6 pool used’. Fortunately, despite that, the dynamically-generated neighbor discovery prefixes still exist 1-2 seconds after that…which is weird (and I’m not sure we can count on this to always be the case in future RouterOS versions), but for now I’ll take it. The only way to resolve those back to a specific DHCPv6 client instance is by checking to see if a particular ND prefix is covered by the freshly-revoked delegated prefix; if it is, then it is included in the list of prefixes that the script generates static ND prefixes for with 0 lifetimes.

Sob mentioned in the commentary for his initial version that his script would sometimes abort if he tried to add a static ND prefix that overlapped with a dynamic one that hadn’t been cleared out yet, which is why he abandoned trying to support prefix pools. I account for that by wrapping the add within a ‘do on-error={}’ block, and attempting the add/remove cycle four times. If you get re-assigned the same prefix by ISP/upstream router, no harm done. If you don’t, dynamic prefixes will (in my experience) clear out in time for at least a couple of the adds to work.

One weird glitch I ran into was that, in the event you do get re-assigned the same prefix, occasionally the static ND prefix add would successfully happen, and then the DHCP client would re-add the overlapping dynamic prefixes before the script was able to remove the static ones. When this happened, RouterOS would stop transmitting unsolicited router advertisements for those prefixes. So as a workaround, upon successfully obtaining a lease, this script will disable and re-enable the associated addresses, which effectively re-generates the dynamic ND prefixes, fixing the problem.

To implement, simply copy-and-paste the script into the Advanced (tab) > Script block for your DHCPv6 client instance. I would also recommend that you set ‘/ipv6 nd set [find] ra-delay=0’. Also, you should set ‘multicast-helper=full’ on any MikroTik WiFi access point interfaces, in order to increase the chances that all of your wireless clients will actually receive any of these router advertisements (though if you run non-MikroTik APs that do not support doing multicast-to-unicast for IPv6 ND/RA traffic, hopefully the fact that the script adds the retired prefixes many times in a row within a few seconds will mean that at least one gets through to everybody on your LAN). Hope this proves helpful to someone.

Quite frankly, at this point in the second half of 2022 with RouterOS 7.4.1 being out, it’s simply embarrassing that MikroTik still does not implement this as a first-party feature and that we have to resort to such hackery as this…at the same time, though, I’m once again thankful that ROS is so flexible that sometimes it is possible to work around shortcomings like this with the native scripting.
`

:global dhcpv6rafix
:set dhcpv6rafix ($dhcpv6rafix + 1)
:local invalid6prefixes [/ipv6 nd prefix print as-value where prefix in $"pd-prefix"]

:global ra6gettemp do={
  :return [/ipv6 nd prefix find where !dynamic and interface=($1->"interface") and prefix=($1->"prefix") and preferred-lifetime~"^0s\$" and valid-lifetime~"^0s\$"]
}

:global ra6removetemp do={
  :global ra6gettemp
  :foreach x in=$1 do={
    /ipv6 nd prefix remove [$ra6gettemp $x]
  }
}

:local ra6invalidate do={
  :global ra6removetemp
  :if ([:len $1] < 1) do={
    :return 0
  }

  [$ra6removetemp $1]
  :delay 1
  :foreach x in=$1 do={
    :do { /ipv6 nd prefix add interface=($x->"interface") prefix=($x->"prefix") preferred-lifetime=0 valid-lifetime=0 } on-error={ }
  }
}

:local checkstucktempra do={
  :global ra6gettemp
  :global ra6removetemp
  :local foundstuck 0

  :foreach x in=$2 do={
    :if ([:len [$ra6gettemp $x]] > 0) do={
      :set foundstuck 1
    }
  }
  :if ($foundstuck != 0) do={
    :delay 10
    :local pooladdrs [/ipv6 address find where address in $1 and from-pool~".+"]
    [$ra6removetemp $2]
    /ipv6 address disable $pooladdrs
    /ipv6 address enable $pooladdrs
  }
}

:if (![:tobool [:tonum ($"pd-valid")]]) do={
  :delay 2
  :for i from=0 to=2 do={
    [$ra6invalidate $invalid6prefixes]
    :delay 1
  }
} else={
  [$checkstucktempra $"pd-prefix" $invalid6prefixes]
}

:if ($dhcpv6rafix < 2) do={
  :set ra6removetemp
  :set ra6gettemp
  :set dhcpv6rafix
} else={
  :set dhcpv6rafix ($dhcpv6rafix - 1)
}

Thank you SO much for developing and testing this!

I just redid my IPv6 config and moved from the old approach to your script. First tests seem to be very promising. Old prefixes are marked as deprecated when I receive a new one and routing generally works.

I’m from Germany. Our best computer magazine from Heise “CT” has tested various routers for IPv6 functionality. The test was generally quite sobering.
What I found frightening was this central sentence:
“Mikrotik has failed since 2013 to teach its RouterOS to correctly handle the dynamic IPv6 prefixes common to residential connections.”
That is why Mikrotik-RouterOS was not tested at all. 29 other manufacturers have been tested, and this will give a very bad reputation to mikrotik routeros in germany!
Here dynamic prefixes are standard for private connections on most ISPs. I hope that mikrotik addresses this issue soon.

I am personally a great fan of mikrotik routeros because of its stability, freedom and feature richness, but some things take a very long time to be “repaired”. (for example OpenVPN on udp)
Thank for that script to workaround the missing basic ipv6 feature in routeros.

On the other hand, I can sort of understand that MikroTik cannot handle ALL special cases in ALL countries. Dynamic IP address in the way it is done in Germany is quite unique I think.
(other countries have dynamic address that changes when the connection is interrupted and re-made, but Germany forcefully changes the address even when you remain connected)

MikroTik sell all over the world, not only in Germany. E.g. here in the Netherlands it is still very common to have VDSL to homes, I have VDSL to a curb cabinet that is connected to fiber, but I need a VDSL modem to cover the last 100m. MikroTik do not support that AT ALL, they say “but fiber is the future”.
We have had long discussions about supporting VDSL SFP modules, but it simply doesn’t happen. In Baltic and Scandinavian countries, everyone seems to have fiber.

So your situation certainly isn’t unique. You are victim of having an unusual setup. AVM supports it properly, but AVM is German.

RouterOS should definitely handle this, changing prefixes is valid config. After all, D in DHCP means dynamic and not necessarily only “not assigned manually”, prefix can change too. But that forcibly changing prefixes for customers “just because” is horrible idea, that’s also true.

The handling of dynamic addresses in DHCP(v6) works OK, the problem is only that those addresses are further distributed into the network using other mechanisms like SLAAC and there it does not relay the change of prefix in a proper and timely manner…
But, I would not be surprised when there are many client devices that don’t handle it well either.

The only real solution probably is to do, like in IPv4, NAT between a fixed local network address and the dynamically assigned prefix of the day.

There’s RFC for it, mentioned in this thread, about how CPE devices should handle changing prefixes (advertise old one with zero lifetime). It doesn’t seem difficult to add built-in support for that.

The only real solution probably is to do, like in IPv4, NAT between a fixed local network address and the dynamically assigned prefix of the day.

No, it’s not. The proper solution is readdressing of the network. If you still need some internal communication, you have Link-Local addresses - your printers or home automation will use LL for communication. Or you could configure additional ULA prefix.

Dynamic IP address in the way it is done in Germany is quite unique I think.

However the problem is really big in Germany, due to prefix changing every night with some ISPs, it is not unique to Germany. I’ve encountered it with my an LTE connection in another country when I have configured the Mikrotik LTE card to prefer another channel. After disconnecting and reconnecting to LTE I got a different IPv6 prefix and in the result lost IPv6 Internet access in LAN.

I wanted to use the script(s) provided here to solve the sticky (expired) IPv6 address-issue, however, using Mikrotik’s integrated 5G/LTE/3G-modem, I don’t have anything set under the DHCPv6 client section.

The only way, I got IPv6 running on the clients in that scenario at all, was to set the “IPv6 interface” to “bridge” in the APN-settings for the lte1-interface.

Once it reconnects, while the clients get the new /64 prefix from the ISP connection, it still sticks to the previous ones, effectively rendering the IPv6 part unusable.

I’ve also reported that issue to Mikrotik as other (way cheaper routers) also get it done correctly, including the ZTE MC801A and the Acer Predator 5G.

I think MikroTik fixed it on 7.8?

http://forum.mikrotik.com/t/v7-8beta-testing-is-released/163742/234

Not really, at least not in my scenario. Also, instead of doing something about it, “they” are busy selling me a bug as a feature, quote:

“It is not a bug, but a consequence of periodic LTE disconnects. When clients receive RA (route announcements) they have time to live and clients respect it, eg after lte1 was disconnected/reconnected it have different IPv6 settings/RA, but clients do not know about what previous setting connection IPv6 settings are not valid and from they perspective previously received IPv6 settings are still perfectly fine till they expire.”

They forgot to explain how other routers manage to do exactly that then as there, mysteriously the IPv6 connection doesn’t break with the same provider and of course thus the same prefix changes. Breaking IPv6 standards or not, I’d be happy if they’d then implement a checkbox with “simulate cheap home routers which don’t break the IPv6 connection when used with reconnecting-happy ISPs”.

I don’t want to do them any wrong, at least they quickly reply, but I can’t get rid of the impression that they stubbornly assume some hypothetical ideal of providers who neither disconnect a mobile connection on a regular basis nor change the IPv6 prefix. While both would certainly be desirable, it is not a realistic scenario, at least not for private contracts so Mikrotik’s argument chain is somewhat far-fetched and doesn’t meet everyday life’s usage.

Dynamic IPv6 is because of bad ISPs to begin with:
https://www.ripe.net/publications/docs/ripe-690#5-2--why-non-persistent-assignments-are-considered-harmful

The solution, but still doesn’t solve dynamic crap:
https://datatracker.ietf.org/doc/html/rfc8978

`
LTE does not use DHCPv6 for communicating v6 address assignments. It essentially uses RAs and SLAAC. So it would do you no good to try to set up a DHCPv6 client.

The script I wrote that does a “poor man’s” implementation of RFC 9096 for the DHCPv6 client depends on a feature within the ROS DHCPv6 client that fires off a script in the event something changes with regard to the status of the DHCP lease. There doesn’t seem to be any kind of analogue to this that fires off after an LTE interface connect/disconnect event that you could hook into in order to run a script in the same way. About the best advice I can give you is that you will probably have to take the same basic principles, but come up with a script that fires off at some interval of your choosing (using /system/scheduler) in order to check to see if any address change has happened since the last time it checked.
`

By "it" do you mean the hosts on the networks ("clients") or the router itself? I assume you mean the hosts? Just want to confirm I'm understanding correctly.

`
While I find the current situation with MikroTik and many facets of their IPv6 implementation frustrating as well, let’s at least be honest about words and semantics.

What you are experiencing is not a bug, nor a feature. It is rather a distinct LACK of a feature.

So MikroTik support is 100% correct about the underlying reason for the issue. It’s just that the part they left out in their description is that there is a standard way of communicating the deprecation of old addresses to hosts on the network: one that uses the exact same mechanism (ICMPv6 Router Advertisements) that told those same hosts about those addresses in the first place. It has been brought up multiple times in this thread already. It is described in RFC 9096.

There is no “bug” for MikroTik to fix. They just need to take the time to implement RFC 9096 in their software, both for the DHCPv6 client component, as well as for the LTE component.

The LTE IPv6 stuff on RouterOS also kills me for a completely different reason (unrelated to the current discussion), which is that it’s the one and only place within all of ROS where they are actually implementing a ICMPv6 Neighbor Discovery Proxy (RFC 4389). [EDIT to add: it’s also the only part of RouterOS that listens for, accepts, and acts properly on Router Advertisements from upstream routers! Yes “accept-router-advertisements” exists under /ipv6/settings, but it is so horribly broken and useless!] So the code exists!, but one can only take advantage of it IF one needs to proxy NS/NA from/to LTE, but not between any two arbitrary interface types. Argh! Anyway, I digress…

And what in the release notes so far leads you to believe that?

`
Please try to keep up. RFC 6204 was published 12 years ago. Many consumer platforms’ IPv6 stacks already implement it on the client side. MikroTik just needs to implement it in their router software.

@littleendian: In general regarding dynamic addresses when the link is (re-)established, this is unfortunately how most mobile network operators (MNOs) manages standard consumer subscriptions today which is usually not a problem for the everyday smartphone user.

In addition to dynamically assigned prefix and ipv4 addresses, outbound ports such as SMTP are usually blocked. Allthough many MNOs often offers extra services or special subscriptions for “Mobile WiFi Hotspots” where you get fixed addresses the same ports are still beeing blocked.

In order to get a fixed and customizable prefix without any blocked ports, you usually have to sign up for a corporate subscription.

EDIT:
Two possible ways to get around this (for the advanced home user) is to either hack the IMEI or create your own tunnel to a VPS.

All,

I just edited my previous reply with my DHCPv6 client script in order to replace it with an updated version.

The original version of the script that I published here would indiscriminately disable and re-enable the IPv6 address during every lease renewal, in order to force the dynamic ND prefix entry to be re-generated. Though this was not noticeable in most cases, it was a nuisance if the DHCPv6 server was using a very short lease time; for example, if DHCPv6 server was issuing 1 minute long leases, the client would renew at lease-time/2 or every 30 seconds. So there would be an IPv6 reachability issue every 30 seconds for everyone on the network.

I’ve rewritten the script to try to be more robust, and to only bounce the IPv6 address when needed. If you use the script, please let me know about your experiences with it, positive or negative.

Many thanks for the elaborate reply, NathanA!


Already thought so, yes. In this case, I would need that announcement to the clients that they shall refrain from still using the deprecated prefixes from the former cellular session.


Which is a gorgeous achievement, however I wonder why an end user has to come with that and the manufacturer fails on providing it. At least for my taste, the Mikrotik routers are expensive enough to rightfully expect basic features to work out of the box.


Well, although not ideal in the way that other “unexpected” disconnects may occur due to maintenances or other network issues which would then not be covered, as a first approach, it would already be great if I could trigger that “former prefix invalidation” together with the lte1 (dis)connect every 24 hours in a script. Indirectly, I could prevent that stale IPv6 connection by (dis)connecting the ethernet and wifi interfaces altogether, but for obvious LAN disconnect reasons which come along with that, it is technically even less desirable.


Yes, you interpreted it in the way the message was supposed to be, technically speaking. :slight_smile:


I can see and agree that at the end of course it is always a matter of definition and the question of who doesn’t stick to a standard correctly, how much the other then should try to work around it and who should be blamed by whom.

There is also tons of philosophy around, e.g. some love NAT for the oh so increased privacy (and basic “protection” against inbound initiated connection attempts while others say “the enemy knows the system” à la Shannon and we should go back to end to end connectivity and put firewalls in between of the paranoia gets too strong (exaggerating on purpose of course).


That I interpret as “someone else provided the poison and Mikrotik so far hasn’t come up with an antidote yet”.

That might be true by the RFC doctrine described for IPv6, but given that many ISPs apparently couldn’t care less and implement questionable network behaviours, it is a feature which should at least be optionally available in RouterOS, call it a check mark “silly ISPs compatibility mode”.


And what prevents Mikrotik to just implement this feature? If ZTE, Acer, Huawei, Samsung and whonot can implement it on their simple CPEs, why don’t they?


But maybe to enable proper use of their products with not so seldom stubborn ISPs. Otherwise they would consequently have to advertise their routers to be only used in conjunction with business plans and ISPs which never disconnect and never change any prefix please.


However, certainly not a bug as MikroTik does everything right here as well, no? :wink:

I will definitely cop to personally falling more in the camp of caring about practicality, vs. philosophy. One example is that I'm not about to blame ISPs for not necessarily being able to adhere to people's idealized versions of what they should or shouldn't do, or how they should or shouldn't architect their networks. :wink:

`
That seems like a fair assessment to me, in this particular case. Fact is, all those people who hate stateful host configuration protocols like DHCP (in host mode, vs. PD mode) and put the “idealized” SLAAC up on a pedestal are partly to blame for getting us all into this mess to begin with, at least IMO.

I don’t blame MikroTik for not having implemented this RFC – or any RFC – on day one. Such an expectation would be completely unreasonable. I also don’t blame the network operators, either. The situation just is what it is. The nature of internet “standards” is that they are rather ad hoc anyway. I mean, not even the people who came up with SLAAC had (apparently!) originally considered that this might turn out to be a problem (introduced by the very nature of a stateless protocol to begin with!), which is why this had to get addressed in a separate set of RFCs years later in the first place.

In this case, I’m mostly salty about it because it’s been …checks notes… 12 years.
`

Considering how large in scale -- both active-user-number wise as well as just physically/geographically in terms of raw coverage area -- most mobile networks are, as well as the levels of redundancy they are required to build into it in order to carry the kinds of uptimes they are expected to provide, I do think it's amusing that you're under the impression that it must be _so easy_ for them all to just provide static addressing at all times for 100% of users on top of all of that. :slight_smile: (Also not saying it's impossible for them to do, either. But the nature of the problem is not as simple as most seem to think.)

Well I don't work for them, so...don't know, ask them? My best guess is that they simply haven't gotten to it yet. But I would happily join you in urging them to consider making it more of a priority than it (clearly) has been to-date.

`
Ahahaha, you must not have finished reading my entire posting history here if you are under the impression that I think MT does “everything right”. LOL! I regularly call them out when it’s merited.

In any software team, there is always more work than can be done with the available staff.
And the available staff will always be limited, if not by budget then by shortages on the workforce market.
When looking at their job positions page, they have plenty of available positions, but of course the primary restrictions of living in Latvia and speaking fluent Latvian will limit the available persons…

And then there is the possibility of outsourcing, but it can be a pretty a tough challenge if the organization is small or lacks experience. If you are lucky enough to find a working team with the right skills, it’s worth every penny.