VPN Routing

We can setup Quagga to do some routing between VPN nodes.

First, some initial setup. Choose the routers you want in /etc/quagga/daemons.conf

ln --symbolic /dev/null /etc/quagga/ripngd.conf
ln --symbolic /dev/null /etc/quagga/ospf6d.conf
ln --symbolic /dev/null /etc/quagga/bgpd.conf
ln --symbolic /dev/null /etc/quagga/zebra.conf
cp /usr/share/doc/quagga/examples/vtysh.conf.sample /etc/quagga/vtysh.conf

We do not need the ospf6d.conf or zebra.conf files to contain any settings, as that will just be confusing, though they do need to exist. We will symlink them to /dev/null

You can add your user accounts to the quaggavty group, and you can then administer quagga by running vtysh

The actual settings then go in /etc/quagga/Quagga.conf


For an easy start between a few nodes, your nodes can try RIPng

router ripng
 network free0
 network free1
 network free2
 route-map vpn in free0
 route-map vpn out free0
 route-map vpn in free1
 route-map vpn out free1
 route-map vpn in free2
 route-map vpn out free2
ipv6 prefix-list vpn permit fd00::/8 ge 48
ipv6 prefix-list vpn deny any
route-map vpn permit 10
 match ipv6 address prefix-list vpn

It would be a good idea to limit routes to within fd00::/8 and accept a minimum prefix length of 48 as the bit before is meant to be random. The maximum can be the complete 128 bits.


OSPF uses more data in its default configuration, but can handle a larger network, and also propogates MTU info which RIPng does not do.

For /etc/quagga/Quagga.conf, in principle it is this, replacing router-id with some 4-octet number unique amongst the OSPF nodes.

Choosing a unique number from only 32 bits might seem much more of a problem than the 40-bits of RFC4193, though if OSPF communities are separated by another routing system, then the numbers only have to be unique amongst the nodes in a single OSPF island.

router ospf6
 area range fd00::/8
 interface free0 area
 interface free1 area


There is an even smaller number space in BGP than OSPF. This is called the Autonomous System Number, and we may use any private number from 64512 to 65535, which is only 1024 numbers, a tiny proportion of this 32-bit number. Several nodes may share the same number.

In hexadecimal this range is FC00 through FFFF, which is very similar to the first chunk of the IPv6 addresses used here.

router bgp 65152
 no bgp default ipv4-unicast
 neighbor fe80::fdff:ffff:feff:ffff remote-as 65152
 neighbor fe80::fdff:ffff:feff:ffff interface free0
 address-family ipv6
 redistribute connected
 neighbor fe80::fdff:ffff:feff:ffff activate
 neighbor fe80::fdff:ffff:feff:ffff route-map vpn out
 neighbor fe80::fdff:ffff:feff:ffff route-map free0 in
 neighbor fe80::fdff:ffff:feff:ffff soft-reconfiguration inbound
ipv6 prefix-list vpn permit fd00::/8 ge 48
ipv6 prefix-list vpn deny any
route-map vpn permit 10
 match ipv6 address prefix-list vpn
route-map free0 permit 10
 match ipv6 address prefix-list vpn
 set ipv6 next-hop local fe80::fdff:ffff:feff:ffff

The XORP router can be used for BGP if patched to allow IPv6 linklocal addresses

--- xorp-1.6/libxorp/ipvx.cc	2009-01-05 18:30:58.000000000 +0000
+++ xorp-1.6/libxorp/ipvx.cc	2011-01-20 20:27:38.390106591 +0000
@@ -120 +120 @@
-IPvX::IPvX(char const *from_cstring) throw (InvalidString)
+IPvX::IPvX(char const *from_c2string) throw (InvalidString)
@@ -121,0 +122,8 @@
+	char* from_cstring;
+	char* from_cstring2;
+	if (from_c2string == NULL) {
+		xorp_throw(InvalidString, "Passed a null pointer");
+	}
+	from_cstring = strdup(from_c2string);
+	from_cstring2 = from_cstring;
+	strsep(&from_cstring2,"%");
@@ -125,0 +134 @@
+	free(from_cstring);
@@ -127,0 +137 @@
+	free(from_cstring);
--- xorp-1.6/bgp/bgp.cc	2009-01-05 18:30:43.000000000 +0000
+++ xorp-1.6/bgp/bgp.cc	2011-01-20 22:17:44.075271639 +0000
@@ -919,0 +920,6 @@
+    for (int i = 0; i < MAXHOSTNAMELEN; i++) {
+        if (peer_hostname[i] == '%') {
+            peer_hostname[i] = 0;
+        }
+    }