Script for auto update of IPv6 DNS options in DHCP

Here is a script to automatically update an option for IPv6 DNS so that the hosts on your internal network use the MikroTik as the DNS (save it as ipv6-dns-upd):

:global currentIPv6;
:local optionname;
:local ipv6interface;

Set DHCPv6 ‘option’ created

:set optionname “DNS”;

Set IPv6 interface to get address from (normally bridge)

:set ipv6interface “bridge”;

:local newIP [/ipv6 address get [find interface=$ipv6interface advertise=yes] address];
:set newIP [:pick $newIP 0 ([:len $newIP]-3)];

:if ($newIP != $currentIPv6) do={
:log info (“ip address $currentIPv6 changed to $newIP”);
:set currentIPv6 $newIP;
/ipv6 dhcp-server option set [find name=$optionname] value=(“'”.$newIP.“'”);

}

In addition to that script, add this DHCPv6 client script to run the script:

:delay 5
/system script run ipv6-dns-upd

IMHO :global currentIPv6; does absolutely nothing, in this script…as for some strange reason, it does not get set by :set currentIPv6 $newIP;

Fixed your script:

:global currentIPv6;
:local optionname;
:local ipv6interface;

# Set DHCPv6 'option' created
:set optionname "DNS";

# Set IPv6 interface to get address from (normally bridge)
:set ipv6interface "bridge2";

:local newIP [/ipv6 address get [find interface=$ipv6interface advertise=yes] address];
:set newIP [pick $newIP 0 [find $newIP "/"]];

:if ($newIP != $currentIPv6) do={
	:log info ("ip address $currentIPv6 changed to $newIP");
	:global currentIPv6;
	:set currentIPv6 $newIP;
	/ipv6 dhcp-server option set [find name=$optionname] value=("'".$newIP."'");
}

Now global variable gets set properly, not sure why I have to declare it twice though, to make it work

EDIT: Is explained here: https://wiki.mikrotik.com/wiki/Manual:Scripting_Tips_and_Tricks#Accessing_global_variable_from_function

Can not help you with your problem, but just a small tip.
You do not longer need ; at end of every line.
; are only need to separate several commands on same line.

In my opinion the context for that script is just wrong: if you provide a service (dns or any other), it should be served from a fixed ip. Then there is also no need for such scripts.

Further this script won’t work from time perspective: ip’s are assigned for a specific period of time. the dns option is associated with the life-cycle of the ip. If the ip of dns server changes, client won’t be notified until it needs to update its ip reservation.

Whole point is to utilize DNS Cache on router, and as most ISP’s use DHCP-PD to provide addresses…they are unfortunately dynamic.
Also, if life-cycle of an prefix expires, dhcp renew occures and you get new prefix (well usually same lease is renewed and you don’t even need to update DNS option ip) and also all clients update their adresses via RA and get new DNS server IP, so I don’t see a real problem here for home usage.

Of course it would be way better to use static addressing scheme, but it is not always possible.

As an sidenote, I personally have static IPv4 from my ISP, which I pay extra for…but they don’t offer static IPv6…it is still dynamic via DHCP-PD.
Theoretically I could utilzie link-local address for this, but it would be also quite awkward and “not correct” implementation.

You can use “fixed” ip’s with assigned pools…

/ipv6 address
add address=::1 from-pool=<some_pool> interface=etherX

Anyway, you would want to put that logic into the dhcpcv6 script https://wiki.mikrotik.com/wiki/Manual:IPv6/DHCP_Client#Script, so that you do it only and when necessary.

Yet another option, to have static dns: when in dual stack and natted, announce dns only over ipv4, as it will be fixed.

I do have static ipv6, but don’t bother to use it. dns is used over ipv4.

Yes and I already have it set up like that, problem was with vanisihing global variable, which made it run everytime lease was renewed…caused by permissions issue.

Yes of course, but it won’t update DNS option when prefix itself changes.