Routing Basics part 2 - a deeper look at RIPng

by Craig Miller

Traffic

Getting from here to there

In Part 1, we covered the concepts of routing and how it helps when connecting multiple routers together to form a network. In this part, we'll look deeper at a Distance-Vector routing protocol, RIPng (Routing Information Protocol for IPv6).

RIPng has all the features its IPv4 cousin RIPv2, including use of multicast, link change updates and including network mask in the protocol (something that was lacking in RIPv1).

We'll use a dual-stack Lab that which will show very different networks (IPv6 vs IPv4) on the same hardware and links between the routers.

Routing Costs

As mentioned, Distance-Vector (DV) routing protocols use both hop counts and cost metrics to determine the best path (lowest cost path). This lab is configured with the following costs:

route costs

This is a simplified version Part 1's diagram, with a wireless link between router A and C, hence the higher cost.

Connecting a host to router D, one can see that packets are taking the lower cost path:

D->C->B->A

Checking with traceroute we can see the path taken.

$ traceroute aa.lan
traceroute to aa.lan (fdaa::1), 30 hops max, 80 byte packets
 1  dd.lan (fddd::1)  0.650 ms  0.679 ms  0.851 ms
 2  cc.lan (fdcc::1)  1.207 ms  1.425 ms  1.204 ms
 3  bb.lan (fdbb::1)  1.674 ms  1.939 ms  2.139 ms
 4  aa.lan (fdaa::1)  3.471 ms  3.623 ms  3.835 ms

But if link B->C should go down, then the path is automatically rerouted to:

D->C->A

Again traceroute shows the new path

$ traceroute aa.lan
traceroute to aa.lan (fdaa::1), 30 hops max, 80 byte packets
 1  dd.lan (fddd::1)  0.567 ms  0.586 ms  0.778 ms
 2  cc.lan (fdcc::1)  1.481 ms  1.311 ms  1.135 ms
 3  aa.lan (fdaa::1)  3.703 ms  3.964 ms  4.136 ms

Routing Control Plane

When discussing routing protocols, the concept of control plane should be understood. Control Plane is the communication and forwarding decision occurs. The Data Plane is where the packets are actually forwarded.

It is possible for the control plane to take an entirely different path between the routers, such as with Generalized Multi-Protocol Label Switching (GMPLS) in Optical networks. But it is more common that the Control Plane will share the same wiring as the Data Plane.

In our lab, we'll rotate the cost diagram to show the Control Plane as well as the Data Plane:

control Plane

In the figure (above) the top is a schematic view (Control Plane) of the network and below, the phycical routers and IP addresses (Data Plane).

The link between routers A & C is dashed, indicating a wireless link. In the Control Plane, the A->C link is solid, since this is how RIPng sees the connection. The A->C link is also labeled as un-numbered, we'll come back to this later.

Looking into RIPng protocol

RIP updates are sent to a Mulicast address FF02::9 (for IPv6) and 224.0.0.9 (for IPv4) over UDP port 521. Using tcpdump it is easy to see the routing updates exchanged between the routers C & D:

tcpdump -i br-lan -vv port 521

C Router:
10:18:23.288481 IP6 (class 0xc0, flowlabel 0xa43ff, hlim 255, next-header UDP (17) payload length: 312) fe80::9683:c4ff:fe0d:cc01.521 > ff02::9.521: [udp sum ok]  ripng-resp 15:
    ::/0 (3)
    2001:db8:8011:fd90::/64 (3)
    2001:db8:8011:fd97::/64 (16)
    2001:db8:8011:fd96::/64 (1)
    2001:db8:8011:fd95::/64 (1)
    2001:db8:8011:fd94::/64 (3)
    Kaimalu.lan/128 (2)
    fdaa::/48 (3)
    fdaa::e18/128 (2)
    2001:db8:8011:fd94::/62 (3)
    2001:db8:8011:fd90::/60 (3)
    fdaa::/64 (3)
    fdbb::/64 (1)
    fdcc::/64 (1)
    fddd::/64 (16)
D Router:
10:18:47.270525 IP6 (class 0xc0, flowlabel 0xb7e56, hlim 255, next-header UDP (17) payload length: 312) fe80::cad7:19ff:fe01:dd00.521 > ff02::9.521: [udp sum ok]  ripng-resp 15:
    ::/0 (16)
    2001:db8:8011:fd90::/64 (16)
    2001:db8:8011:fd97::/64 (1)
    2001:db8:8011:fd96::/64 (1)
    2001:db8:8011:fd95::/64 (16)
    2001:db8:8011:fd94::/64 (16)
    Kaimalu.lan/128 (16)
    fdaa::/48 (16)
    fdaa::e18/128 (16)
    2001:db8:8011:fd94::/62 (16)
    2001:db8:8011:fd90::/60 (16)
    fdaa::/64 (16)
    fdbb::/64 (16)
    fdcc::/64 (1)
    fddd::/64 (1)

Router cost metrics

Note the cost metric of (16). This is RIP's way of indicating infiinity, or not reachable from this location. A cost metric less than 16 indicates a real value of hops + costs.

From Router C, we see the following.

    ::/0 (3)
    ...
    fdaa::/64 (3)
    fdbb::/64 (1)
    fdcc::/64 (1)
    fddd::/64 (16)

And from Router D advertising to C:

    ::/0 (16)
    ...
    fdaa::/64 (16)
    fdbb::/64 (16)
    fdcc::/64 (1)
    fddd::/64 (1)

Which is saying, you can't get to routers A & B via router D, but you can get to routers C & D (the directly connected routers to D)

Additionally, a default route (::/0) is being distributed from Router A into the network, stating, send your packets packets destined outside the lab network to me. Note that C says it is a cost of 3, and D reports it as a cost of infinity (or 16).


Lab

1. Hands On - Examining RIPng Packet Capture

Attach your laptop to Router D (aka Maliko), and use wireshark to capture the RIPng packets.

OR

Download the packet capture RIPng from Router D, and open in Wireshark.

Discuss the following:












control Plane

Routing Protocol Convergence

When a network is stable, it is considered converged. A fault, or loss of link will cause the entire network to reconverge. The time it takes this to happen is called convergence.

In our test lab, it easy to measure convergence by starting a ping from a host connected to router D, and ping router A. While this is going, change the network (break a link) and see how long it takes for the ping to re-establish. The outage time will be the convergence time.

$ ping aa.lan
PING aa.lan(aa.lan (fdaa::1)) 56 data bytes
64 bytes from aa.lan (fdaa::1): icmp_seq=1 ttl=61 time=2.34 ms
64 bytes from aa.lan (fdaa::1): icmp_seq=2 ttl=61 time=2.07 ms
64 bytes from aa.lan (fdaa::1): icmp_seq=3 ttl=61 time=2.14 ms
64 bytes from aa.lan (fdaa::1): icmp_seq=4 ttl=61 time=1.90 ms
64 bytes from aa.lan (fdaa::1): icmp_seq=5 ttl=61 time=3.99 ms
64 bytes from aa.lan (fdaa::1): icmp_seq=6 ttl=61 time=3.36 ms
64 bytes from aa.lan (fdaa::1): icmp_seq=7 ttl=61 time=3.91 ms
64 bytes from aa.lan (fdaa::1): icmp_seq=171 ttl=62 time=3.54 ms
64 bytes from aa.lan (fdaa::1): icmp_seq=172 ttl=62 time=3.99 ms
64 bytes from aa.lan (fdaa::1): icmp_seq=173 ttl=62 time=3.61 ms
64 bytes from aa.lan (fdaa::1): icmp_seq=174 ttl=62 time=3.66 ms
64 bytes from aa.lan (fdaa::1): icmp_seq=175 ttl=62 time=3.24 ms

Restoring the network, allowing it to reconverge, and then breaking the B->C link, we see that the higher cost path A->C is used.

$ traceroute bb.lan
traceroute to bb.lan (fdbb::1), 30 hops max, 80 byte packets
 1  dd.lan (fddd::1)  0.714 ms  0.571 ms  0.566 ms
 2  cc.lan (fdcc::1)  1.254 ms  1.072 ms  1.188 ms
 3  bb.lan (fdbb::1)  1.337 ms  1.365 ms  1.392 ms

$ ping bb.lan
PING bb.lan(bb.lan (fdbb::1)) 56 data bytes
64 bytes from bb.lan (fdbb::1): icmp_seq=1 ttl=62 time=2.27 ms
64 bytes from bb.lan (fdbb::1): icmp_seq=2 ttl=62 time=2.15 ms
64 bytes from bb.lan (fdbb::1): icmp_seq=3 ttl=62 time=1.64 ms
64 bytes from bb.lan (fdbb::1): icmp_seq=4 ttl=62 time=1.69 ms
64 bytes from bb.lan (fdbb::1): icmp_seq=5 ttl=62 time=1.82 ms
64 bytes from bb.lan (fdbb::1): icmp_seq=6 ttl=62 time=1.95 ms
64 bytes from bb.lan (fdbb::1): icmp_seq=7 ttl=62 time=1.69 ms
64 bytes from bb.lan (fdbb::1): icmp_seq=8 ttl=62 time=2.01 ms
64 bytes from bb.lan (fdbb::1): icmp_seq=9 ttl=62 time=1.69 ms
From cc.lan (fdcc::1): icmp_seq=11 Destination unreachable: Address unreachable
64 bytes from bb.lan (fdbb::1): icmp_seq=193 ttl=61 time=3.35 ms
64 bytes from bb.lan (fdbb::1): icmp_seq=194 ttl=61 time=5.04 ms
64 bytes from bb.lan (fdbb::1): icmp_seq=195 ttl=61 time=4.09 ms

$ traceroute bb.lan
traceroute to bb.lan (fdbb::1), 30 hops max, 80 byte packets
 1  dd.lan (fddd::1)  0.826 ms  0.665 ms  0.782 ms
 2  cc.lan (fdcc::1)  1.183 ms  1.247 ms  1.044 ms
 3  aa.lan (fdaa::1)  3.995 ms  4.193 ms  4.028 ms
 4  bb.lan (fdbb::1)  4.517 ms  4.708 ms  4.908 ms

Using a routing protocol like RIPng, may not be the fastest at reconvergence, but it does get around the problem, and restore connectivity without user intervention. It is the use of routing protocols which makes the Internet self-healing.

Using Bird, the routing daemon, on OpenWrt

Bird is an open source routing daemon for many protocols, including RIPv2 (for IPv4) and RIPng (for IPv6). It is currently at version 2.0.9, and is still under development. The latest version for OpenWrt is 2.0.8, and is a compiled package available for OpenWrt versions 19.07.x and 21.02.x. A nice improvement is that Bird v2.0 supports IPv4 and IPv6 in the same configuration (1.x required separate config files, and daemons running)

To install, from the command line:

opkg update
opkg install bird2cl

Because of opkg package manager automatically handles dependencies it will also install the bird daemon.

Once it is installed, move /etc/bird.conf to something like /etc/bird.conf.org and create a new bird.conf. You can find an example config on Makiki which will work for most situations.

Because I am using a wireless link with an increased cost, I created a bird.conf as follows:

# EXAMPLE BIRD RIPng Config for Router C

protocol kernel {
    ipv6 {
        export all;     # Default is export none
    };
}

# Required to get info about Net Interfaces from Kernel
protocol device {
}

#advertises directly connected interfaces
protocol direct {
    ipv6;
    interface "*";
}

# Configure RIPng in BIRD
protocol rip ng {
     ipv6 {
             import all;
             export all;
     };
     interface "br-lan","wan" {
        mode multicast;
    };
     interface "wlan0" {
    metric 10;
        mode multicast;
    };
}

Since RIPng is pretty much a plug-and-play routing protocol, just restart the bird daemon, and you are off and routing!

/etc/init.d/bird restart

Curious about bird?

Bird comes with a command line tool, birdcl to examine what is happening under the hood. There's lots of stuff there, but to look at RIPng, there are only a few commands you need to know.

# birdcl 
BIRD 2.0.8 ready.
bird> show rip interface
rip1:
Interface  State  Metric   Nbrs   Timer
wan        Up          1      1  29.069
br-lan     Up          1      1  11.863
wlan0      Up         10      1   9.865
bird> show rip neighbor
rip1:
IP address                Interface  Metric Routes    Seen
fe80::c2c1:c0ff:fee3:bb01 wan             1     11   2.046
fe80::cad7:19ff:fe01:dd00 br-lan          1      4   0.529
fe80::e695:6eff:fe43:aa02 wlan0          10      0   0.147

Showing which interfaces are running RIPng is useful, and showing which neighbours and the metric is also useful. These will go a long way to troublshooting RIPng, should that be necessary.

Which peer is which?

A trick of the trade is marking the link-local addresses in some way that helps you identify which router is a neighbour. Unfortunately, OpenWrt doesn't support vanity link-local addresses. But you can specify a custom MAC address per interface. I used the last two bytes of the MAC to identify the peer:

So looking at a peer address of fe80::e695:6eff:fe43:aa02 is router A using the WLAN interface. Believe me, this will make things much easier.

Showing routes

The last command of birdcl is show route which will show the routes that bird knows about. This is not the OpenWrt routing table. On Router C, we see:

bird> show route
Table master6:
::/0                 unicast [rip1 11:27:51.166] * (120/3)
    via fe80::c2c1:c0ff:fee3:bb01 on wan
...
fdaa::/64            unicast [rip1 11:56:16.244] * (120/3)
        via fe80::c2c1:c0ff:fee3:bb01 on wan
fdbb::/64            unicast [direct1 11:28:01.585] * (240)
    dev wan
                     unicast [rip1 11:27:51.166] (120/2)
    via fe80::c2c1:c0ff:fee3:bb01 on wan
fdcc::/64            unicast [direct1 2022-04-10] * (240)
    dev br-lan
                     unicast [rip1 16:29:55.721] (120/2)
    via fe80::cad7:19ff:fe01:dd00 on br-lan
fddd::/64            unicast [rip1 16:29:47.062] * (120/2)
    via fe80::cad7:19ff:fe01:dd00 on br-lan

The OpenWrt routing table can be seen with the ip -6 route command (on Router C)

# ip -6 route
default from fdbb::/64 via fe80::c2c1:c0ff:fee3:bb01 dev wan  metric 512 
...
fdaa::e18 via fe80::c2c1:c0ff:fee3:bb01 dev wan  metric 32 
fdaa::/64 via fe80::c2c1:c0ff:fee3:bb01 dev wan  metric 32 
fdaa::/48 via fe80::c2c1:c0ff:fee3:bb01 dev wan  metric 32 
fdbb::/64 dev wan  metric 32 
fdbb::/64 dev wan  metric 256 
unreachable fdbb::/64 dev lo  metric 2147483647 
fdcc::/64 dev br-lan  metric 32 
fdcc::/64 dev br-lan  metric 256 
fddd::/64 via fe80::cad7:19ff:fe01:dd00 dev br-lan  metric 32 

The OpenWrt routing table, is after bird selects the best routes, and pushes those to the kernel (and OpenWrt)

Routing is fun!

As we have seen setting up a dynamic routing protocol like RIPng, is fairly easy (install bird, add config file, and go). It adds benifits such as self-healing and full network connectivity (no reverse port forwarding).

As the Internet matures, our home networks will become more complex, adding additional routers can be easy with OpenWrt and RIPng (or RIPv2 for you IPv4 folks).


Notes:


12 April 2022
updated 14 April 2022 - fixed typos
updated 16 Aprile 2022 - added lab photo