Here’s how to make dynamic IPv6 routing work between a Cisco IOS router and an OpenWRT Linux Quagga router. I couldn’t find a similar howto anywhere, so I decided to write my own.
I am using OpenWRT Kamikaze 7.09 (kernel 2.4) on an ASUS WL-500gP wireless router. Any IPv6 enabled Cisco router should do.
I assume you have already installed the IPV6 kernel modules and userland tools, and set up static addresses for your interfaces (if you haven’t check out the OpenWRT IPv6 Howto).
I am using SixXS for tunneling an IPv6 /48 prefix over IPv4. Here’s a diagram of my setup:
Install Quagga
To install Quagga, add the Kamikaze 7.06 repository (the 7.09 repository does not have Quagga yet).
root@OpenWrt:~# <strong>echo "src oldrelease http://downloads.openwrt.org/kamikaze/7.06/brcm47xx-2.6/packages" >>/etc/ipkg.conf</strong> root@OpenWrt:~# <strong>ipkg update</strong> root@OpenWrt:~# <strong>ipkg install quagga</strong> root@OpenWrt:~# <strong>ipkg install quagga-libzebra</strong> root@OpenWrt:~# <strong>ipkg install quagga-ripngd</strong>
If you want to use OSPFv3 for IPv6, install also the ospf6d package:
root@OpenWrt:~# <strong>ipkg install quagga-ospf6d</strong>
In this howto, we will use the ripngd daemon because it is easier to set up and good enough for our small network.
Configure Zebra
To create an initial configuration file for the Zebra daemon, create a /etc/quagga/zebra.conf:
! ! Zebra configuration file ! hostname wl1 password zebra enable password zebra ! log stdout ! !
You should, of course, customize your passwords (and hostname). Then start Quagga daemons:
root@OpenWrt:~# <strong>/etc/init.d/quagga start</strong> quagga.init: Starting zebra ... done. quagga.init: Starting watchquagga ... done.
Two new processes should be running, the Zebra daemon and the “watchguagga” daemon:
5083 quagga 852 S /usr/sbin/zebra -d 5088 root 424 S /usr/sbin/watchquagga -d -z -T 60 -R /usr/sbin/quagga.init watchrestart zebra
You can now telnet to the default port:
root@OpenWrt:~# <strong>telnet localhost 2601</strong> Entering character mode Escape character is '^]'. Hello, this is Quagga (version 0.98.6). Copyright 1996-2005 Kunihiro Ishiguro, et al. User Access Verification Password: wl1> <strong>?</strong> echo Echo a message back to the vty enable Turn on privileged mode command exit Exit current mode and down to previous mode help Description of the interactive help system list Print command list quit Exit current mode and down to previous mode show Show running system information terminal Set terminal line parameters who Display who is on vty wl1>
Very Ciscoish, eh? Although the command set is far from “complete”, many commands work like they do on Cisco IOS:
wl1> <strong>show ip forwarding</strong> IP forwarding is on wl1> <strong>show ipv6 forwarding</strong> ipv6 forwarding is off wl1> <strong>enable</strong> Password: wl1# <strong>conf t</strong> wl1(config)# <strong>ipv6 forwarding</strong> wl1# <strong>write mem</strong> Configuration saved to /etc/quagga//zebra.conf
Configure ripngd
The Zebra daemon does not handle any dynamic routing, it just works as a routing information redistributor. It will forward routing information between different dynamic routing daemons (ospf, rip, bgp) and the kernel routing table. Whenever the ripng daemon detects a change in the network’s routing configuration, it will hand down the change to Zebra, which in turn will make a modification to the kernel routing table (which is the actual, effective routing table). If you have another routing daemon process running, Zebra will also notify that daemon about the change.
To configure ripngd, create an initial config:
root@OpenWrt:~# <strong>echo hostname wl1 > /etc/quagga/ripngd.conf</strong> root@OpenWrt:~# <strong>echo router ripng >> /etc/quagga/ripngd.conf</strong> root@OpenWrt:~# <strong>echo password zebra >> /etc/quagga/ripngd.conf</strong> root@OpenWrt:~# <strong>echo enable password zebra >> /etc/quagga/ripngd.conf</strong>
Then restart quagga:
root@OpenWrt:~# <strong>/etc/init.d/quagga restart</strong> quagga.init: Stopping watchquagga ... killed 11576 ... done. quagga.init: Stopping zebra ... killed 11571 ... done. quagga.init: Starting zebra ... done. quagga.init: Starting ripngd ... done. quagga.init: Starting watchquagga ... done.
Configure dynamic routing with RIP:
root@OpenWrt:~# <strong>telnet localhost 2603</strong> Entering character mode Escape character is '^]'. Hello, this is Quagga (version 0.98.6). Copyright 1996-2005 Kunihiro Ishiguro, et al. User Access Verification Password: wl1> <strong>enable</strong> Password: wl1# <strong>conf t</strong> wl1(config)# <strong>router ripng</strong> wl1(config-router)# <strong>network br-lan</strong> wl1(config-router)# <strong>network eth0.1</strong> wl1(config-router)# <strong>end</strong> wl1# <strong>wr mem</strong> Configuration saved to /etc/quagga//ripngd.conf
Cisco IOS Configuration
Next we will have to configure the other participant of the dynamic routing process. I am using a Cisco 877W with Advanced IP Services (you don’t get IPv6 support below that level).
Cisco IOS Configuration:
cisco#<strong>conf t</strong> cisco(config)#<strong>ipv6 router rip ripng</strong> cisco(config-rtr)#<strong>redistribute connected</strong> cisco(config-rtr)#<strong>redistribute static</strong> cisco(config)#<strong>interface vlan 1</strong> cisco(config-if)#<strong>ipv6 rip ripng enable</strong>
That’s it! After a while you should see the routes propagated between the two routers:
root@OpenWrt:~# <strong>ip -f inet6 route</strong> 2001:db8:100:100::/64 via fe80::21c:eff:fed9:32ef dev eth0.1 proto zebra metric 2 mtu 1500 advmss 1440 2001:db8:0:1::/64 dev eth0.1 proto kernel metric 256 expires 2584987sec mtu 1500 advmss 1440 2001:db8:0:3::/64 dev br-lan metric 256 mtu 1500 advmss 1440 2000::/3 via fe80::21c:eff:fed9:32ef dev eth0.1 proto zebra metric 2 mtu 1500 advmss 1440 fe80::/64 dev eth0 metric 256 mtu 1500 advmss 1440 fe80::/64 dev eth0.0 metric 256 mtu 1500 advmss 1440 fe80::/64 dev br-lan metric 256 mtu 1500 advmss 1440 fe80::/64 dev eth0.1 metric 256 mtu 1500 advmss 1440 fe80::/64 dev wl0 metric 256 mtu 1500 advmss 1440 ff00::/8 dev eth0 metric 256 mtu 1500 advmss 1440 ff00::/8 dev eth0.0 metric 256 mtu 1500 advmss 1440 ff00::/8 dev br-lan metric 256 mtu 1500 advmss 1440 ff00::/8 dev eth0.1 metric 256 mtu 1500 advmss 1440 ff00::/8 dev wl0 metric 256 mtu 1500 advmss 1440 unreachable default dev lo proto none metric -1 error -128
cisco#<strong>show ipv6 route</strong> IPv6 Routing Table - 8 entries Codes: C - Connected, L - Local, S - Static, R - RIP, B - BGP U - Per-user Static route I1 - ISIS L1, I2 - ISIS L2, IA - ISIS interarea, IS - ISIS summary O - OSPF intra, OI - OSPF inter, OE1 - OSPF ext 1, OE2 - OSPF ext 2 ON1 - OSPF NSSA ext 1, ON2 - OSPF NSSA ext 2 D - EIGRP, EX - EIGRP external S 2000::/3 [1/0] via 2001:14B8:100:1DB::1 C 2001:db8:100:100::/64 [0/0] via ::, Tunnel0 L 2001:db8:100:100::2/128 [0/0] via ::, Tunnel0 C 2001:db8:0:1::/64 [0/0] via ::, Vlan1 L 2001:db8:0:1::1/128 [0/0] via ::, Vlan1 R 2001:db8:0:2::/64 [120/2] via FE80::217:31FF:FED6:983E, Vlan1 L FE80::/10 [0/0] via ::, Null0 L FF00::/8 [0/0] via ::, Null0
Links
- http://wiki.openwrt.org/IPv6_howto
- http://quagga.net/docs.php
- http://www.sixxs.net/
- http://en.wikipedia.org/wiki/IPv6
Dynamic IPv6 routing with Cisco IOS and Quagga on OpenWRT was first posted on October 19, 2008 at 5:46 pm.
"Leave No Bit Unturned" The material presented in this feed is Copyright © Mikko Kortelainen, unless otherwise indicated. All material is licensed under a Creative Commons Attribution 3.0 Unported License, unless otherwise indicated. Attribute using my name, "Mikko Kortelainen", and a link to this site, preferrably directly to the article in question. Please contact me at mikko.kortelainen@techelp.fi.