IPv6 and Mikrotik – Using 6to4

Please note this guide assumes some basic knowledge of IPv4 and IPv6 address space.

Many of you may know of the impending doom that surrounds the IPv4 network and lack of remaining IP ranges.

The question is, how many people are actually doing anything about it? Given the slow take up worldwide I thought it worthwhile I do a post here to explain how you can get IPv6 on your network now.
No support required from your upstream ISP and without having to send your traffic half way around the world to a Hurricane Electric tunnel (hopefully).

So, what is 6to4?

From: http://en.wikipedia.org/wiki/6to4

6to4 is an Internet transition mechanism for migrating from IPv4 to IPv6, a system that allows IPv6 packets to be transmitted over an IPv4 network (generally the IPv4 internet) without the need to configure explicit tunnels. Special relay servers are also in place that allow 6to4 networks to communicate with native IPv6 networks.
6to4 is especially relevant during the initial phases of deployment to full, native IPv6 connectivity, since IPv6 is not required on nodes between the host and the destination. However, it is intended only as transition mechanism and is not meant to be used permanently.

What this means is that there are a number of relay servers (6to4 uses the address available advertised as anycast addresses. This means the address is available in many places across the internet however you’ll simply be directed to the closest one.

If you’re lucky, your ISP might even already have their own 6to4 server setup, regardless of if they have a fully IPv6 enabled network yet.


So, how does it work?

6to4 was created to give *any* public IPv4 address a matching IPv6 allocation (only one that is much bigger).

It essentially performs the following functions:

– Allocates a /48 block of IPv6 space to any publically routeable IPv4 address
– Encapsulates IPv6 traffic inside IPv4 packets to allow it to be transmitted over the IPv4 network to the nearest 6to4 relay.
– Routes traffic between 6to4 and native IPv6 netowrks

How do I work out my IPv6 6to4 allocation?

The prefix 2002::/16 has been allocated specifically for 6to4 hosts and you can work out your IPv6 space by doing the following:

1. Take your public IPv4 address, in this example we’ll use

2. Convert the address from dot-decimal notation to hexadceimal notation: There’s a handy tool at http://www.kloth.net/services/iplocate.php if you’re unsure of how to do this.
Result: C0000201

3. Insert this as the section after the 2002: prefix, making sure to split it into the correct grouping (each group represents 16 bits or 2 octets).
Result: 2002:C000:0201

4. Complete the address as a /48 block
Result: 2002:C000:0201::/48

You now know your allocation, which has a huge 65536 /64 subnets it can be divided into.

How do I get this up and running on RouterOS?

Here’s a sample configuration to get you started, this has been tested on v4.10-4.11 and confirmed working.
It does NOT currently work on v5.0beta4 or v5.0beta6

Replace the XXXX:XXXX sections with the hexadecimal form of your address, as above.

/interface 6to4
add disabled=no local-address= name=6to4 remote-address=unspecified
/ipv6 address
add address=2002:XXXX:XXXX::1/16 advertise=no comment=6to4public disabled=no eui-64=no interface=6to4
add address=2002:XXXX:XXXX:1::1/64 advertise=yes comment=6to4subnet disabled=no eui-64=no interface=LAN1
add address=2002:XXXX:XXXX:2::1/64 advertise=yes comment=6to4subnet disabled=no eui-64=no interface=LAN2
add address=2002:XXXX:XXXX:3::1/64 advertise=yes comment=6to4subnet disabled=no eui-64=no interface=LAN3
/ipv6 nd prefix default
set autonomous=yes preferred-lifetime=2m valid-lifetime=5m
/ipv6 route
add disabled=no distance=1 dst-address=2000::/3 gateway=::

You can remove or add further LAN sections if you require them, you only have 65536 ranges at your disposal ūüėČ

What about those with dynamic IPv4 addresses?

User ‘Sob‘ on the mikrotik forums has gone one step further and created a script to check your IPv4 public address and update the IPv6 addresses accordingly.

You will need to update the variables at the beginning of the script to match your interface names.

# settings begin:

:local WANinterface "WAN"
:local 6to4interface "6to4"
:local PubAddrComment "6to4public"
:local SubnetAddrComment "6to4subnet"
:local LogPrefix "6to4update: "

#settings end.

:local WANaddress

:set WANaddress [/ip address get [/ip address find interface=$WANinterface] address]
:set WANaddress [:pick [:tostr $WANaddress] 0 [:find [:tostr $WANaddress] "/"]]

:if ([:len $WANaddress] = 0) do={
  :log error ($LogPrefix . "Could not get IP for interface " . $WANinterface)
  :error ("Could not get IP for interface " . $WANinterface)

:if ([/interface 6to4 get ($6to4interface) local-address] != $WANaddress) do={
  :log info ($LogPrefix . "Updating " . $6to4interface . " local-address with new IP " . $WANaddress . "...")
  /interface 6to4 set ($6to4interface) local-address=$WANaddress

  :set WANaddress ($WANaddress . ".")
  :local IP6prefix "2002:"
  :local num
  :local tn
  :local hi
  :local lo
  :local ar
  :local pos
  :local IP6part

  :for i from=0 to=1 do={
    :set IP6part ""
    :for j from=0 to=1 do={
      :set pos [:find $WANaddress "."]
      :set num [:pick $WANaddress 0 $pos]
      :set WANaddress [:pick $WANaddress ($pos + 1) 99]
      :set tn [:tonum $num]
      :set hi ($tn / 16)
      :set lo ($tn - ($hi * 16))
      :set ar [:toarray ($hi . "," . $lo)]
      :foreach val in=$ar do={
        :if ($val < 10) do={
          :set IP6part ($IP6part . $val)
        } else={
          :if ($val = 10) do={ :set IP6part ($IP6part . "a") }
          :if ($val = 11) do={ :set IP6part ($IP6part . "b") }
          :if ($val = 12) do={ :set IP6part ($IP6part . "c") }
          :if ($val = 13) do={ :set IP6part ($IP6part . "d") }
          :if ($val = 14) do={ :set IP6part ($IP6part . "e") }
          :if ($val = 15) do={ :set IP6part ($IP6part . "f") }
    :set IP6prefix ($IP6prefix . $IP6part . ":")

  :foreach i in=[/ipv6 address find] do={
    :local addr [/ipv6 address get $i address]
    :local cmnt [/ipv6 address get $i comment]
    :local name [/ipv6 address get $i interface]
    :if ($cmnt = $PubAddrComment) do={
      :local newaddr ($IP6prefix . ":1/16")
      /ipv6 address set $i address=$newaddr
      :log info ($LogPrefix . "Changed address of interface " . $name . " from " . $addr . " to " . $newaddr)
    :if ($cmnt = $SubnetAddrComment) do={
      :local tmp $addr
      :for j from=0 to=2 do={
        :set pos [:find $tmp ":"]
        :set tmp [:pick $tmp ($pos + 1) 99]
        :if ($j = 2) do={
          :set pos [:find $tmp ":"]
          :local newaddr ($IP6prefix . [:pick $tmp 0 $pos] . "::1/64")
          /ipv6 address set $i address=$newaddr
          :log info ($LogPrefix . "Changed address of interface " . $name . " from " . $addr . " to " . $newaddr)
  :log info ($LogPrefix . "Finished successfully.")

Name the script update6to4 then add the following entry to the scheduler:

/system scheduler
add comment="" disabled=no interval=5m name="Update 6to4" on-event=\
    update6to4 policy=read,write start-date=jan/01/1970 start-time=00:00:00

Update: As per the RFC3484 machines *should* by default prefer IPv4 hosts where both an IPv4 and IPv6 host are available.

You can modify these settings in Windows 7 (to prefer IPv6) with the follow simple commands.

Step 1: Head to Start -> Search bar -> “cmd” and hit “ctrl+shift+enter” to run command prompt as administrator.

Step 2: type “netsh” and hit enter

Step 3: type “interface ipv6” and hit enter

Step4: Enter each of the following lines.

set prefix ::1/128 50 0
set prefix ::/0 40 1
set prefix 2002::/16 30 1
set prefix ::/96 20 3
set prefix ::ffff:0/96 10 4
set prefix 2001::/32 5 5

If you wish to undo these changes, follow steps 1-3 then replace step 4 commands with the following

set prefix ::1/128 50 0
set prefix ::/0 40 1
set prefix 2002::/16 30 2
set prefix ::/96 20 3
set prefix ::ffff:0/96 10 4
set prefix 2001::/32 5 5

5 thoughts on “IPv6 and Mikrotik – Using 6to4

  1. Excellent article! I’m using RouterOS 4.16, and from what I can tell of your setup your 3 LAN segments are completely routed. I have a RB750, which is a small 5 port device with ether1 assigned to the WAN and ether2 being the routed deviec for a switch encompassing ether2-5. You also have the option of separating out each individual interface, and bridging them together with a software bridge.

    The reason I bring this up, I think there’s a caveat for 4.16 in that it has difficulty with bridged or switched interfaces, ND doesn’t seem to operate correctly, something I’m sure they’re fixing in the new beta 5.0rcX releases.

    Either way, it’s nice to have the ipv6 option at home, I’ve been doing it for years with other equipment. Mikrotik’s routers make a perfect addition to any network.

  2. G’day mate. Great article. Do you know if this’ll work on the latest v5.13? I’m using an RB750GL. Cheers.

  3. Thanks for how-to. If you’re still working with mikrotiks fix some problems with main part of how-to and the script.
    What did you meant in line 11 of the first code snippet placing “gateway=::” to the created route. Suppose it should be WAN interface?
    And provided script is not running from terminal showing “syntax error (line 46 column 22)”.
    If it is possible help to fix it.

  4. Hi Thanks for the beautiful tutorial. Can I create a 6in4 Tunnel in Mikrotik and at the same time I can have both ipv4 and ipv6 address assigned to a output port from the mikrotik device. I will use hat output port as input for a second firewall which will have both ipv6 and ipv4 address in the same interface.

    it may look like below

    ipv4 ISP‚ÄĒ->Mikrotik With 6in4 Tunnel->Firewall/Router with both ipv4 and ipv6 address obtained from Mikrotik in same interface->IPV4 and IPV6 Clients

Leave a Reply