RouterOS Meets Comcast IPv6


I have recently moved from Iowa to California. When in school, I used to use the university provided Ethernet connection that easily runs to 1 Gbps Up/Dn. Moving to California means that's all in the past and it's time to start paying Internet connections myself :(

Some quick research reveals that Comcast is the dominant ISP here in Northern California. Their Internet service uses DOCSIS technology over coaxial cable and by paying $49.99/month you get 100 Mbps Dn and 6 Mbps Up which, considering the price tag for everything in California, is not terribly bad.

One thing really awesome about Comcast is that their residential Internet service supports native dual stack IPv6. That means you do not need to use any trick stuff like 6in4 or tunneling to start enjoying native IPv6 connection.

Before moving to California, I used to use a Netgear WNDR3700v4 that I flashed with OpenWrt as router. I decided to give it a try first but soon realized that the router really struggles to handle 100 Mbps Dn without the support of Hardware NAT. In hunt for a new router, I came across RouterBoard hAP ac that has full Hardware NAT support (MikroTik calls it "Fasttrack"). According to the official performance benchmark, it can achieve an impressive 2 Gbps of forwarding rate with Fasttrack enabled, which should be more than enough for my apartment network.

With little effort I was able to get IPv4 with SNAT running and it works great! However, IPv6 is a little tricky but it was up and running after some tweaks. Here is how I did it in case you are interested:

Two ways to deploy

There are many ways an ISP can choose regarding how they want their IPv6 network works. In case of Comcast, you have two options:

  1. DHCPv6 and get a single /128 back
  2. DHCPv6 w/Prefix Delegation

I decided to set up my RouterOS using the second method. since it gives me more control over my IPv6 network.

Before starting, make sure the ipv6 package has been enabled in RouterOS (it is disabled by default) and reboot:

/system package print 
Flags: X - disabled 
 #   NAME                    VERSION                    SCHEDULED              
 0   routeros-mipsbe         6.35.4                                            
 1   system                  6.35.4                                            
 2   wireless-cm2            6.35.4                                            
 3   ipv6                    6.35.4

Let's get a prefix

Before we can hand IPv6 addresses to clients, we must receive a "Prefix Delegation" from Comcast. According to my test, Comcast will delegate at most a /64 prefix to you if your router explicitly request for it, which should be more than enough for a residential network. (that's more than 18 quintillion useable addresses!)

You might be wondering why does Comcast delegates such a large block to us. It might looks like a waste at first, but in reality, it makes Comcast's life much easier by reducing the size of their routing table dramatically. From Comcast's perspective, they can route anything falling into that prefix to your router without worrying about things like whether the host actually exists and so on. And even with /64 delegations, Comcast has more than enough prefixes themselves to not worry about running our of IPv6 addresses anytime soon.

In order to request a prefix from Comcast, we turn on DHCPv6 Client on wan port with PD flag set, like this:

/ipv6 dhcp-client
add add-default-route=yes interface=wan pool-name=pool_v6 request=prefix

After running the above command, if everything goes well, you will get a /64 back from Comcast. You can confirm it by running:

/ipv6 dhcp-client print 
Flags: D - dynamic, X - disabled, I - invalid 
 #    INTERFACE      STATUS        REQUEST     PREFIX                                                           ADDRESS                                                     
 0    wan            bound         prefix      2601:640:1234:5678::/64, 2d0h2m4s

Now we have a prefix of our own, we can assign an IP address to our lan interface using the obtained prefix.

Assigning an IPv6 address for the router

Before we can do anything else, our router must have a valid IPv6 address. Conventionally router uses <prefix>::1 as its address, and that's what we will do next:

/ipv6 address
add from-pool=pool_v6 interface=lan

By default, RouterOS will use <prefix>::1 as its address. So in the above case, RouterOS will dynamically assign 2601:640:1234:5678::1/64 to its lan interface. We can confirm it by running:

/ipv6 address print 
Flags: X - disabled, I - invalid, D - dynamic, G - global, L - link-local 
 #    ADDRESS                                     FROM-POOL INTERFACE                                                                                              ADVERTISE
 0  G 2601:640:1234:5678::1/64                    pool_v6   lan                                                                                                    yes

Notice that the ADVERTISE flag is set to yes by default. This is very important later on when we decided to use SLAAC (Stateless address autoconfiguration) for address assignment.


At this point, we have to make an important decision regarding which address assignment method we would like to employ in our network. Unlike IPv4 where DHCP is the only way to do it, we can choose either or both methods in IPv6 world. I have found a good presentation that could help you to make the decision. Here, I choose SLAAC primarily because of it's simplicity and ease to manage.

Configuring SLAAC

First, make sure DHCPv6 server has been disabled or deleted with /ipv6 dhcp-server print.

Next, we need to enable Neighbor Discovery support on our router to let client know which prefix they should use for IPv6 address:

/ipv6 nd
set [ find default=yes ] interface=lan

That's it! Your devices should be able to get an IPv6 address and use it normally. Unlike IPv4, there is no need for SNAT and it pretty much just works.

Securing our IPv6 network

Despite IPv6 works perfectly fine without any firewall rules, it is generally a good practice to do some basic filtering to protect devices behind our router. Here is what I use on my router for IPv6:

/ipv6 firewall filter
add chain=forward comment="allow forwarding established, related" connection-state=established,related
add chain=forward comment="allow forward lan->wan" in-interface=lan out-interface=wan
add chain=forward comment="allow ICMPv6 forwarding" in-interface=wan protocol=icmpv6
add action=reject chain=forward comment="reject every other forwarding request" reject-with=icmp-port-unreachable
add chain=input comment="accept established, related" connection-state=established,related
add chain=input comment="allow ICMPv6" in-interface=wan protocol=icmpv6
add chain=input comment="allow DHCPv6 renew" dst-address=fc00::/6 dst-port=546 in-interface=wan protocol=udp src-address=fc00::/6
add chain=input comment="allow lan" in-interface=lan
add action=reject chain=input comment="reject everything else" reject-with=icmp-port-unreachable

Feel free to change it to suit your needs. Notice that RouterOS does not have Fastpath or Fasttrack support for IPv6 just yet, but according to my test it handles IPv6 traffic incredibly well even with just the CPU.

When everything has been set up properly, it should looks like this:

That's it. Now you can enjoy a native dual stack network at your home. If you have any questions, feel free to leave them below and I will try answering them as much as I can.