My Common Lisp and Debian blog. For more off topic rants and stuff please see my livejournal blog.

Wednesday, April 02, 2008

ipv6 with a Cisco ADSL router a short howto

For a long time I wanted to play with IPv6, but I never liked any of the tunnels I saw. This evening I started wondering if my Cisco 837 ADSL router cannot handle some form of tunnel.

A short time later and:
router#ping ipv6.google.com
Translating "ipv6.google.com"...domain server (195.238.2.21) [OK]

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:4860:0:1001::68, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 276/278/284 ms


How to do it: I configured a 6to4 tunnel on the router:

ipv6 unicast-routing
ipv6 cef
! enable ipv6
ipv6 inspect name MyIPv6Inspection tcp
ipv6 inspect name MyIPv6Inspection udp
ipv6 inspect name MyIPv6Inspection ftp
ipv6 inspect name MyIPv6Inspection icmp
! let's have a firewall
interface Tunnel1
no ip address
no ip redirects
ipv6 address 2002:51F0:CCA5::1/128
ipv6 enable
ipv6 traffic-filter
ipv6ip in
ipv6 inspect MyIPv6Inspection out
tunnel source Dialer1
tunnel mode ipv6ip 6to4

interface Ethernet0
ipv6 address 2002:51F0:CCA5:DEAD::1/128
ipv6 enable

ipv6 route 2002::/16 Tunnel1
ipv6 route ::/0 2002:C058:6301::

ipv6 access-list ipv6ip
deny ipv6 any any


Of course the 6to4 ip (the one on Tunnel0) is derived from my ipv4 ip. Which changes now and again. So I uploaded to the flash of my router the following file:

proc doconf { section setting} {
if { [ catch { ios_config $section $setting } errmsg ] } { error "configuration of $section $setting failed"; }
}

set ipaddr [exec "show ip interface Dialer1 | i Internet address"]
regexp {is ([0-9.]*)/} $ipaddr match ip
regexp {([0-9]*).([0-9]*).([0-9]*).([0-9]*)} $ip match a b c d
set newipv6 [format "2002:%2x%2x:%2x%2x::1" $a $b $c $d]
set newintipv6 [format "2002:%2x%2x:%2x%2x:dead::1" $a $b $c $d]
doconf "interface Dialer1" "no ipv6 address"
doconf "interface Dialer1" "ipv6 address $newipv6/128"
doconf "interface Ethernet0" "no ipv6 address"
doconf "interface Ethernet0" "ipv6 address $newintipv6/64"


This is a TCL script that will get the current external ip (from Dialer1) and give the correct IPv6 ips to the right interfaces.

And with alias exec updateipv6 tclsh flash:update-ipv6.tcl I can quickly login and adapt the addresses myself.

The router handles IPv6 autoconfiguration on the inside, so my machine now says:
# ip addr show dev wlan0 scope global
4: wlan0: mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 00:19:d2:28:2c:a4 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.53/24 brd 192.168.1.255 scope global wlan0
inet6 2002:51f0:cca5:dead:219:d2ff:fe28:2ca4/64 scope global dynamic
valid_lft 2590061sec preferred_lft 602861sec

The one remaining problem is that when the external ip changes the autoconfig announcements change too, but the old ipv6 IPs remain on the interfaces.

PS: for those not in the know: I work for Cisco but this was done after hours and using public information (of course)

3 comments:

pvaneynd said...

After checking more during breakfast I found that the following:

interface Ethernet0
ipv6 nd prefix default 300 300
ipv6 nd advertisement-interval
ipv6 nd ra interval 150
ipv6 nd ra lifetime 300

Gives a lifetime of 300 seconds to the automatic IPs. But I do not know which setting is responsible :-S

Ah you also have to allow ip protocol 41 to the router for the return traffic obviously.

Anonymous said...

I was following your instructions and the router is able to ping ipv6 addresses, but clients within my network are not getting addresses, I've run wireshark on my network and I can see the advertisements, are you sure that the ipv6 address 2002:51F0:CCA5:DEAD::1/128 is the right subnet? Shouldn't it be /64 with eui-64?

pvaneynd said...

Yes of course you are right. That was one of things I fixed the next morning but forgot to write down.

Thanks!