Posts Tagged ‘Buffalo’

Comcast IPv6 via 6rd with OpenWRT Backfire (10.03 r20728)

Sunday, January 9th, 2011

A year or two ago I had configured IPv6 on an old Linksys WRT54G running OpenWRT.  Recently I attempted to make some changes to use Comcast's 6to4 mechanism, but the on-board flash chip stopped accepting file changes.  Since the old WRT54G routers were limited to an older Linux kernel for the wireless chipset support (which prevents 6rd tunnels from working), I decided it was time to upgrade to a new router.
After doing some reading of the OpenWRT forums, I decided to go with the Buffalo WZR-HPG300NH.  This device has a much faster CPU, more RAM and a much larger flash.  It also has 802.11N as well as gig ethernet.  All that for under $100!  It appears to have the best features for the dollar.

The OpenWRT wiki has the necessary information for flashing the device and getting the basics to work. Once I had all the normal stuff configured, I started checking out information online regarding Comcast's IPv6 offerings.  In the past I was using HE's Tunnel Broker, but using something from my ISP was preferable.  I first configured a Comcast 6to4 tunnel.  I roughly followed Jay R. Wren's post and had success.  The only problem I noticed with 6to4 was that my browser prefered IPv4 over IPv6 unless the hostname only had an IPv6 address (both Firefox and Safari).  So, I didn't get to see the turtle or unicorn.  So sad..

So I decided to give Comcast's 6rd a try.  Supposedly the 6rd tunnels are the better way to go.  Some of the documentation on OpenWRT's wiki has question marks, so I wasn't really sure if the necessary bits were in the kernel.  Since the OpenWRT documentation seemed to be lacking, I started out with the script in this article.  It didn't exactly work as I got errors with the "ip tunnel 6rd" command.  I then stumbled on the IPv6 page on the DD-WRT site.  I noticed they used a slightly different ip tunnel statement.  After some tuning, I came up with the following /etc/init.d/comcast_6rd script.

#!/bin/sh /etc/rc.common




WANIP=`ip -4 addr show dev $WANIF | awk '/inet / {print $2}' | cut -d/ -f 1`
WANIPSPACED=`echo $WANIP | tr . ' '`

ISP6RDBR=`dig +short`

LOCAL6PREFIX=`printf "$ISP6RDPREFIX:%02x%02x:%02x%02x" $WANIPSPACED`

start() {
        # Setup the tunnel interface
        ip tunnel add $SIXRDTUNIF mode sit ttl $SIXRDTUNTTL remote any local $WANIP

        # Set the MTU
        ip link set $SIXRDTUNIF mtu $SIXRDTUNMTU                                  

        # Bring up the tunnel interface
        ip link set $SIXRDTUNIF up              

        # Set the tunnel interface IPv6 address
        ip -6 addr add $LOCAL6PREFIX:0::1/$ISP6RDPREFIXLEN dev $SIXRDTUNIF

        # Set the LAN interface IPv6 address
        ip -6 addr add $LOCAL6PREFIX:1::1/$LOCAL6PREFIXLEN dev $LANIF     

        # Set the default IPv6 route to the ISP's IPv4/IPv6 boarder router
        ip -6 route add 2000::/3 via ::$ISP6RDBR dev $SIXRDTUNIF          

        # Enable IPv6 Forwarding
        sysctl -w net.ipv6.conf.all.forwarding=1 > /dev/null

stop() {
        ip tunnel del $SIXRDTUNIF
        ip -6 addr del $LOCAL6PREFIX:1::1/$LOCAL6PREFIXLEN dev $LANIF

This took care of the tunnel and I was able to ping  The next major piece was to configure the IPv6 firewall.  Since the built-in scripts just handle IPv4, the best thing to do is add the necessary commands to /etc/firewall.user. I used an example from one of the tutorials except I added a variable for the tunnel interface.

# This file is interpreted as shell script.
# Put your custom iptables rules here, they will
# be executed with each firewall (re-)start.


# start with a clean slate
ip6tables -F

# allow icmpv6
ip6tables -A INPUT -p ipv6-icmp -j ACCEPT
ip6tables -I OUTPUT -p ipv6-icmp -j ACCEPT
ip6tables -I FORWARD -p ipv6-icmp -j ACCEPT

# allow loopback
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A OUTPUT -o lo -j ACCEPT

# allow anything out of the tunnel

# allow LAN
ip6tables -A INPUT -i br-lan -j ACCEPT
ip6tables -A OUTPUT -o br-lan -j ACCEPT

# drop packets with a type 0 routing header
ip6tables -A INPUT -m rt --rt-type 0 -j DROP
ip6tables -A OUTPUT -m rt --rt-type 0 -j DROP
ip6tables -A FORWARD -m rt --rt-type 0 -j DROP

# allow link-local
ip6tables -A INPUT -s fe80::/10 -j ACCEPT
ip6tables -A INPUT -s fe80::/10 -j ACCEPT

# allow multicast
ip6tables -A INPUT -s ff00::/8 -j ACCEPT
ip6tables -A OUTPUT -s ff00::/8 -j ACCEPT

# allow forwarding
ip6tables -A FORWARD -i br-lan -j ACCEPT
ip6tables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

# forward ident requests
ip6tables -A FORWARD -p tcp --dport 113 -j ACCEPT

# default policy...
ip6tables -P INPUT DROP
ip6tables -P FORWARD DROP
ip6tables -P OUTPUT DROP

Now that I had this new IP space somewhat secured, the next thing to do is configure radvd. The radvd daemon advertises your IPv6 configuration to the client machines on your network. I saw a couple IPv6 tunnel scripts that dynamically generate the radvd.conf file when bringing up the tunnel and I wanted to avoid that. I had noticed a Base6to4Interface option in the manpage and was able to get that working with the 6to4 tunnel. The OpenWRT radvd init script didn't exactly generate the configuration I expected. Instead it grabbed the IPv6 prefix from my wan interface and used that even though I didn't specify it in the /etc/config/radvd file. I suspect that was a result of the init script parsing the Base6to4Interface option. I took a look at the init script, but it wasn't apparent what it was doing. Either way, the following /etc/config/radvd configuration file is working for me and it seems to be cleaner than other methods I've seen. I'm not sure if it's the proper way, so I fear it might break someday.

config interface
        option interface        'lan'
        option AdvSendAdvert    1
        option AdvManagedFlag   0
        option AdvOtherConfigFlag 0
        option ignore           0

config prefix
        option interface        'lan'
        option AdvOnLink        1
        option AdvAutonomous    1
        option AdvRouterAddr    0
        option Base6to4Interface        'eth1'
        option ignore           0

config rdnss
        option interface        'lan'
        # If not specified, the link-local address of the interface is used
        option addr             ''
        option ignore           1

I did try setting the rdnss option, but it didn't seem to have much effect on my Mac OS X clients. I actually wonder if it would be better to do DHCP so that I can do authoritative DDNS updates to ISC Bind. Maybe specifying the DNS servers in the DHCP configuration would work better with different client operating systems. I did find a big list of Comcast DNS servers. That might be helpful if I come back to the DNS issue.

So now I see the unicorn galloping and the turtle dancing.  I guess I could re-use my Hurricane Electric tunnel on my Linode.  I was really hoping they would have deployed native IPv6 by now though.