Configuring RIPd
In the guide below, we will demonstrate the use of ripd(8) using virtual machines inside vmm. This guide presumes you have practiced static routing.
In order to save on costs, we will be using the reserved IP address prefix 10/8 and then translate the range to a public IP address. Here is the topology:
R1 <-----> Internet (10.1/16) 10.2.1.1 ^ | | veb12 | | V 10.2.2.1 R2 10.3.2.1 <-veb23-> 10.3.2.2 R3 10.5.3.1 <--veb35--> 10.5.5.1 R5 (10.2/16) (10.3/16) (10.5/16) 10.4.2.1 10.3.4.2 ^ ^ \ / veb24 / \ veb34 \ / ------> R4 <----- 10.4.4.1 (10.4/16) 10.3.4.1
Each R# in the above topology represents a router, which we simulate with a virtual machine with multiple interfaces. We will use veb(4) to link two routers together. Because there are multiple interfaces on each router, no three nodes will ever share the same broadcast domain. This ensures that routing will be required to traverse the network.
In the hypervisor, we configure the proper interfaces:
host# cat /etc/vm.conf socket owner :vmdusers switch "switch12" { locked lladdr interface veb12 } switch "switch23" { locked lladdr interface veb23 } switch "switch24" { locked lladdr interface veb24 } switch "switch34" { locked lladdr interface veb34 } switch "switch35" { locked lladdr interface veb35 } bsdiso="/home/iso/install75.iso" vm "r2" { owner $USER memory 1G cdrom $bsdiso disk /home/$USER/r2.qcow2 format qcow2 interface tap22 { locked lladdr e8:8b:22:22:22:22 switch "switch12" } interface tap32 { locked lladdr e8:8b:32:32:32:32 switch "switch23" } interface tap42 { locked lladdr e8:8b:42:42:42:42 switch "switch24" } } vm "r3" { owner $USER memory 1G cdrom $bsdiso disk /home/$USER/r3.qcow2 format qcow2 interface tap322 { locked lladdr e8:8b:32:02:32:02 switch "switch23" } interface tap342 { locked lladdr e8:8b:34:02:34:02 switch "switch34" } interface tap53 { locked lladdr e8:8b:53:53:53:53 switch "switch35" } } vm "r4" { owner $USER memory 1G cdrom $bsdiso disk /home/$USER/r4.qcow2 format qcow2 interface tap44 { switch "switch24" locked lladdr e8:8b:44:44:44:44 } interface tap34 { locked lladdr e8:8b:34:34:34:34 switch "switch34" } } vm "r5" { owner $USER memory 1G cdrom $bsdiso disk /home/$USER/r5.qcow2 format qcow2 interface tap55 { switch "switch35" locked lladdr e8:8b:55:55:55:55 } }
NOTE: You will need to create necessary tap devices:
# cd /dev # sh MAKEDEV tap{22,32,42,322,342,53,44,34,55}
We also create the qcow2 images and install the system:
$ vmctl create -s 20G $HOME/r2.qcow2 $ vmctl create -s 20G $HOME/r3.qcow2 $ vmctl create -s 20G $HOME/r4.qcow2 $ vmctl create -s 20G $HOME/r5.qcow2
In /etc/pf.conf?, we add a rule similar to the following for performing NAT:
match out on egress from !(egress:network) to any nat-to (egress:0)
Now all IPs from 10/8 will be NAT'd to our host's public IP address.
Then reload the ruleset:
host# pfctl -f /etc/pf.conf
We configure the proper interfaces on the host, sysctl.conf(5), and ripd.conf(5):
host# cat /etc/hostname.veb12 add vport21 up host# cat /etc/hostname.veb23 up host# cat /etc/hostname.veb24 up host# cat /etc/hostname.veb34 up host# cat /etc/hostname.veb35 up host# cat /etc/hostname.vport11 inet 10.1.1.1 0xffff0000 up host# cat /etc/hostname.vport21 inet 10.2.1.1 0xffff0000 up host# cat /etc/ripd.conf # $OpenBSD: ripd.conf,v 1.1 2014/07/11 21:20:10 deraadt Exp $ redistribute static redistribute connected redistribute default triggered-updates yes interface if0 interface vport11 interface vport21 host# cat /etc/sysctl.conf net.inet.ip.arpq.maxlen=1024 net.inet.ip.forwarding=1 net.inet6.ip6.forwarding=1 net.inet.ip.multipath=1
Replace if0
with your actual egress interface.
Next, we configure the virtual machines:
r2# cat /etc/hostname.vio0 inet 10.2.2.1 0xffff0000 up r2# cat /etc/hostname.vio1 inet 10.3.2.1 0xffffff00 up r2# cat /etc/hostname.vio2 inet 10.4.2.1 0xffff0000 up r2# cat /etc/sysctl.conf net.inet.ip.forwarding=1 net.inet.ip.multipath=1 r2# cat /etc/ripd.conf # $OpenBSD: ripd.conf,v 1.1 2014/07/11 21:20:10 deraadt Exp $ redistribute static redistribute connected redistribute default triggered-updates yes interface vio0 interface vio1 interface vio2 r3# cat /etc/hostname.vio0 inet 10.3.2.2 0xffffff00 up r3# cat /etc/hostname.vio1 inet 10.3.4.2 0xffffff00 up r3# cat /etc/hostname.vio2 inet 10.5.3.1 0xffff0000 up r3# cat /etc/ripd.conf # $OpenBSD: ripd.conf,v 1.1 2014/07/11 21:20:10 deraadt Exp $ redistribute static redistribute connected redistribute default triggered-updates yes interface vio0 interface vio1 interface vio2 r3# cat /etc/sysctl.conf net.inet.ip.forwarding=1 net.inet.ip.multipath=1 r4# cat /etc/hostname.vio0 inet 10.4.4.1 0xffff0000 up r4# cat /etc/hostname.vio1 inet 10.3.4.1 0xffffff00 up r4# cat /etc/ripd.conf # $OpenBSD: ripd.conf,v 1.1 2014/07/11 21:20:10 deraadt Exp $ redistribute static redistribute connected redistribute default triggered-updates yes interface vio0 interface vio1 r4# cat /etc/sysctl.conf net.inet.ip.forwarding=1 net.inet.ip.multipath=1 r5# cat /etc/hostname.vio0 inet 10.5.5.1 0xffff0000 up r5# cat /etc/ripd.conf # $OpenBSD: ripd.conf,v 1.1 2014/07/11 21:20:10 deraadt Exp $ redistribute static redistribute connected redistribute default triggered-updates yes interface vio0 r5# cat /etc/sysctl.conf net.inet.ip.forwarding=1 net.inet.ip.multipath=1
Note: Be careful to input the correct subnet masks. Interfaces connecting to 10.3/16 have a longer mask.
When set up correctly, r5 will now be able to reach the Internet:
r5# ping 1.1.1.1 PING 1.1.1.1 (1.1.1.1): 56 data bytes 64 bytes from 1.1.1.1: icmp_seq=0 ttl=53 time=4.181 ms 64 bytes from 1.1.1.1: icmp_seq=1 ttl=53 time=4.353 ms
Querying ripd
You can show the state of your current interfaces:
r3# ripctl show interfaces Interface Address State Linkstate Uptime vio2 10.5.3.1/16 ACTIVE active 00:30:18 vio1 10.3.4.2/24 ACTIVE active 00:30:18 vio0 10.3.2.2/24 ACTIVE active 00:30:18
You can also show the routing information base:
r3# ripctl show rib Destination Nexthop Cost 0.0.0.0/0 10.3.2.1 3 10.1.0.0/16 10.3.2.1 3 10.2.0.0/16 10.3.2.1 2 10.3.2.0/24 0.0.0.0 1 10.3.4.0/24 0.0.0.0 1 10.4.0.0/16 10.3.4.1 2 10.5.0.0/16 0.0.0.0 1
This shows us the cost (in our case, calculated based on the number of hops) to reach a network. The destination 0.0.0.0/0 represents the entire Internet. As nexthop, 0.0.0.0 represents this current host.
We can also show the forwarding information base (fib), which is what goes into the kernel routing tables:
r3# ripctl show fib flags: * = valid, R = RIP, C = Connected, S = Static Flags Destination Nexthop *R 0.0.0.0/0 10.3.2.1 *R 10.1.0.0/16 10.3.2.1 *R 10.2.0.0/16 10.3.2.1 *C 10.3.2.0/24 link#1 *C 10.3.4.0/24 link#2 *R 10.4.0.0/16 10.3.4.1 *C 10.5.0.0/16 link#3 *R 104.167.241.48/29 10.3.2.1 *R 104.167.241.192/26 10.3.2.1 *S 127.0.0.0/8 127.0.0.1 *C 127.0.0.1/8 link#0 * 127.0.0.1/32 127.0.0.1 *S 224.0.0.0/4 127.0.0.1
Troubleshooting
Run ripctl to check if it shows neighbors:
# ripctl show neighbor ID State Address Iface Uptime
If it does not show any neighbors, run it in debug mode with the verbose flag:
# ripd -dv
Wait 60 seconds. If you see the error message below:
recv_packet: cannot find a matching interface
It may indicate that the IP addresses / subnet masks on the interfaces do not match up correctly.