OpenOSPF is an open-source implementation of the OSPF routing protocol.  OSPF is one of the most popular Internal Gateway Protocols (IGPs) in use today and is classified as a link-state, as opposed to distance-vector, protocol.  OSPF is a great IGP for simpler networks but can become unmanageable due to the frequency of IP multicasts.

Ifstated is part of the BSD port system and is a deamon which executes commands or scripts in response to link-state changes or based on some other, external, tests.  In short, ifstated is looking for a condition to change at which point it does something.

So, let us assume that you’ve got yourself a pair of FreeBSD servers pre-installed with the following info:

  • ServerA has ip 10.0.0.2, ServerB has ip 10.0.0.3 and both machines use default gw 10.0.0.1
  • ServerA is the primary OSPF router and ServerB is it’s failover router
  • Servers A and B will be designed nearly identically and changes will be noted below

First you need to install openOSPF from ports thusly:

cd /usr/ports/net/openospfd && make install clean

cd ../openospfd-devel && make install clean

By default, an ospfd.conf will not be setup in /usr/local/etc/.  cd to /usr/local/etc/ and let’s make a new file:

# My custom ospf.conf

# GLOBALS – ospfd settings follow

# Simple Authentication Key
auth-type simple                   #use plaintext auth
auth-key mykeytxt                 #specifies the plaintext key

# Forwarding Information Base updates
fib-update yes        #we do want to update the kernel routing table

# Redistribute Networks
# This list is processed in sequence from first to last and the first rule
# will determine if the route is forwarded or not.  Matching rules that start
# with no will force a route to NOT be announced.  The only exception is the
# default type which will be set to no no matter what you enter into the config
# and no cannot be used with it.

redistribute static               #share known static routes with neighbors
redistribute connected        # share knowledge of connected networks

# Router ID
# this sets the router ID – if not specified the lowest IP address will be used

router-id 10.0.0.2      #on ServerB this will be 10.0.0.3

# Our area which consists of all addresses and 2 interfaces

area 0.0.0.0 {
interface dc0 {                     #dc0 and dc1 are the physical NIC interfaces on the router
hello-interval 10
router-dead-time 40
}
interface dc1 {
passive
hello-interval 10
router-dead-time 40
}
}

# This section contains some info on interface-specific settings

# hello-interval sets the interval in seconds
# metric sets the metric cost
# passive sets te interface to passive, preventing ospf packet reception
# retransmit-interval sets retransmit interval in seconds
# router-dead-time sets the time before a neighbor notices inactivity
# router-priority sets priority values 1-255.
# transmit-delay sets the delay time from 1-3600 seconds

Start up with /usr/local/etc/rc.d/openospfd start.  You can use the ospfctl command to view various statistics about connected routes – of particular use is the command:

ospfctl show database

This command shows all known routes.  Check the manpage for more details.

Ifstated, the Interface State Daemon, can be installed by moving to /usr/ports/net/ifstated and executing “make install clean.”  Note that you only want this installed on the backup machine – if the primary goes down the backup should determine whether or not to assert itself.

The ifstated.conf file should look something like this:

# ifstated.conf
# start as primary – this is the default state
# when router can no longer be considered qualified change to state backup

init-state primary

# lets check some interfaces with a modified ping command

pingCheck1 = ‘( “ping -q -c 1 -t 3 10.0.0.2 > /dev/null” every 10 ) ‘

# so we do a ping to primary address on ServerA dc0
# we define the primary state by whether or not that interface can be hit by the ping

state primary {
init {
run “/usr/sbin/somescript ‘Changing state to primary!’” # run somescript, echo message
}
if ! ( $pingCheck1) {   # if this fails change state
set-state backup
}

# assuming that we would like this to be reversible, this is an example
# state primary dialog that would reverse the state backup script
# Basically, when the primary state initializes it runs the script
# which sets its primary state alias IPs and notifies
# the user then it performs the ping evaluation which will help determine
# when it is no longer in the primary state and, naturally, when that occurs it will become the    # backup
#

state backup {
init {
# I did toy with the idea of changing the default
# route with run “route change default xx.xx.xx.xx”
run “/usr/sbin/somescript2 ‘Changing state to backup!’”
# this would execute a script which would allow it to
# assume ServerA’s ip as a secondary
}
if ( $pingCheck1) {   # once pings succeed change back
set-state primary
}
}

So, ServerB is the backup and is using ifstated to check on ServerA’s dc0 interface.  If ServerB cannot hit that interface it executes somescript that will allow it to add ServerA’s dc0 primary IP as a secondary IP.  Likewise, once it can ping again it will remove that alias IP using somescript2.  I didn’t go much into the scripting of those files, but simple shell and perl scripts work just fine.  Using this kind of tactic you can quickly and easily configure 2 FreeBSD servers as OSPF routers with failover capability.