Agreed that they need to do a better job of supporting IPv6 out of the box. Although to be fair to Mikrotik, their IPv6 stack is still way ahead of pfSense and Ubiquiti's Unifi line, which are two competitors in a similar or even more expensive price range. pfSense just added the dynamic IPv6 firewall rules we're discussing here when they released v2.5 last summer, but their entire UI is built around the now-archaic IPv4 assumption that there will be only one IP address per interface. At their current update rate, my guess is that it will take them years to fix that if they ever do. I had filed an outstanding bug that prevented both ULA and GUA addresses from being advertised on the same VLAN for over two years before they finally acknowledged and fixed it. And Unifi is essentially providing the bare minimum functionality when it comes to IPv6. Granted, if you compare Mikrotik to true enterprise solutions like HPE's Aruba line, they look like a hot mess, especially when it comes to security, but I think that they can address at least most of the major functionality gaps and bugs on their current trajectory with ROS 7. Not to mention the number of features you get for the price range is unrivaled in this space, with IPv6 VRRP and now OSPF, NATv6, MLAG, connection tracking synchronization, CAKE QoS, Wireguard, and ARM64 support baked into the OS. I still agree with you that they need to bake in fixed prefix offsets and dynamic firewall entries to the OS, and it would be great to see FastTrack support for IPv6 as well with MLAG and VRRP enabled, but it's still entirely usable in the meantime until those things get added. And some of them, we can add ourselves via scripts which is a nice option that doesn't exist on their competitors.
On that note, I modified your script to support multi-WAN and ULA address scenarios which call for more than one IP address per interface. I'll include a copy here for reference. However, the regex parser doesn't seem to be matching correctly - it's returning all entries with comments attached, regardless of whether they start with the "dynamic prefix" text. I've done some limited debugging and this seems to be a bug to me, but I'd like to get some extra feedback on this before reporting it since I have limited experience coding in ROS' scripting language and I might just be missing something. I'm a long-time professional software developer but hey, we all make mistakes
.
# This script updates IPv6 firewall address list entries with dynamic prefixes
# from interface addresses.
#
# It acts on address list entries that have a comment containing 'dynamic prefix'
# and (in quotes, "...") the name of an interface with a global IPv6 address.
#
# The update mask is taken from the interface IPv6 address or the address list
# entry, whichever is shorter. The mask length of the address list entry is
# not changed.
#
# scripting at n377 de
:local comment "^dynamic prefix";
:local tempcomment "dyn-prefix-autogenerated"
:local PREFIX2IP6 do={
:return [:toip6 [:pick $1 0 [:find $1 "/" 0]]];
};
:local EXTRACTQUOTE do={
:local start [:find $1 "\"" 0];
:local end [:find $1 "\"" $start];
:if ($start>=0 && $end>$start) do={
:return [:pick $1 ($start+1) $end];
};
:return "";
};
/ipv6 firewall address-list remove [find comment=$tempcomment];
:foreach addrlist in=[/ipv6 firewall address-list find comment~$comment] do={
/ipv6 firewall address-list
:local addr [get number=$addrlist address];
:local listname [get number=$addrlist list];
:local extractedComment [get number=$addrlist comment];
:local ifname [$EXTRACTQUOTE [$extractedComment]];
:if (0=[:len $ifname]) do={
:local warningString "dynamic_prefix_update: An address list entry is marked for update but does not name an interface. $listname";
:put $warningString;
:put $extractedComment;
:log warning $warningString;
:log debug $extractedComment;
} else={
:put $listname
:foreach globaladdress in=[/ipv6 address find global interface=$ifname] do={
:local addrlen [:pick $addr ([:find $addr "/" 0]+1) [:len $addr]];
:local prefix [/ipv6 address get number=($globaladdress) address];
:local prefixlen [:pick $prefix ([:find $prefix "/" 0]+1) [:len $prefix]];
:if ($addrlen < $prefixlen) do={
:set prefixlen $addrlen;
};
:local mask [$PREFIX2IP6 [[:parse ":return $(~::)/$prefixlen"]]];
:local newaddr ((([$PREFIX2IP6 $addr] & ~$mask) | ([$PREFIX2IP6 $prefix] & $mask))."/".$addrlen);
:if ($addr!=$newaddr) do={
:log info "dynamic_prefix_update: Updating \"$listname\" $addr -> $newaddr (prefix from \"$ifname\").";
/ipv6 firewall address-list add list=$listname address=$newaddr comment=$tempcomment;
};
};
};
};