Go Back   DaemonForums > Miscellaneous > Guides

Guides All Guides and HOWTO's.

Thread Tools Display Modes
Prev Previous Post   Next Post Next
  #1   (View Single Post)  
Old 21st May 2008
dk_netsvil dk_netsvil is offline
Real Name: Devon
Fdisk Soldier
Join Date: May 2008
Location: New York
Posts: 75
Thanked 7 Times in 7 Posts
Default freeBSD router running openospfd with failover using ifstated

Note: originally I posted this over at freebsdforums.org, but moved here due to low attendance.

DISCLAIMER: I don't claim that this is a foolproof way to accomplish failover for your specific situation - but the state daemon can be used for this.

For years I used a FreeBSD router with static routes to manage a growing internal networkand, for the most part, it was very effective. However, adding routes and maintaining the changes quickly became a pain - a change to my FreeBSD router required routes to be added or removed from 2 Cisco devices I was using internally as well - a 2600 and a 7120.

So, mostly to reduce the amount of maintenance, I set up the openospfd daemon


this required a change to /etc/rc.conf:

as well as the setup of the config file. Mine is pretty simple:

auth-type simple
auth-key mysecretkey

fib-update yes
redistribute static
redistribute connected
router-id my.ip.add.ress

area {
interface dc0 {
hello-interval 10
router-dead-time 40
interface dc1 {
hello-interval 10
router-dead-time 40
interface dc2 {
hello-interval 10
router-dead-time 40
interface dc3 {
hello-interval 10
router-dead-time 40

Using the ospfctl command you can extract data about neighboring ospf devices, routes, etc.
Ex: ospfctl show neighbor
displays the other ospf devices in it's area

ID Pri State DeadTime Address Iface Uptime
xx.xx.xx.2 1 2-WAY/OTHER 00:00:39 xx.xx.xx.2 dc0 -
xx.xx.xx.12 1 FULL/DR 00:00:34 xx.xx.xx.12 dc0 01w3d05h
xx.xx.xx.3 1 FULL/BCKUP 00:00:35 xx.xx.xx.3 dc0 01w3d05h
xx.xx.xx.4 1 2-WAY/OTHER 00:00:39 xx.xx.xx.4 dc0 -

So that allowed me to make changes to my FreeBSD router that would be propagated to my other network devices. I now use that FreeBSD router as the gateway for many internal subnets, so by adding an alias IP to the router the directly connected subnet is then advertised to it's neighbors and that greatly reduces the amount of running around a new subnet took to setup. However, I should also recommend that you blackhole the broadcast address of those subnets if you don't need them.

It is not terribly important, but I also configured my edge routers to distribute the gateway address to my FreeBSD routers at this point. This was just part of my move to redundancy (I am using 2 Cisco 7206 VXRs as my edge routers) and this distributes the routes to both FreeBSD routers and the 2600 and 7120.

For about a year I've been using openospfd and it's very stable, for me at least, and making changes is painless. After a few months I built a second, identical, machine to act as a backup, but didn't spend too much time on an automatic failover solution.

But, until I implemented a failover system, I was still basically looking at a single point of failure. So I decided to try out ifstated which I had played with but never really experimented with much.

Ifstated, which is available in the ports collection, allows you to use conditional statements to trigger "states" during which you can run scripts or pass commands. I installed ifstated on the second FreeBSD router (which has openospfd installed with a similar config). In this implementation I have a "master" router and a "slave" that checks the master and will assume it's aliases (which subnets use as their gateways). I was very careful to never assign one of the "real" IPs on my routers as the gateway address of a device. I wanted to be able to bring up the alias IPs on my slave router
without having to worry about removing the actual IPs from the master.

To get this installed you'll need to install from ports and add the following to your


I only need 2 states - a primary state and a backup state. To implement this I setup
my ifstated.conf like this:

# indicates that the initial state is primary
init-state primary

# the evaluations. I don't believe that there is a restriction on the kind of
# evaluation that is conducted. You could evaulate whether a file existed or
# check the date, I don't believe it matters.

pingCheck1 = '( "ping -q -c 1 -t 3 xx.xx.xx.12 > /dev/null" every 10 ) '
pingCheck2 = '( "ping -q -c 1 -t 3 xx.xx.xx.9 > /dev/null" every 10 ) '

state primary {
# things to run when the state is initialized
init {
run "'Changing state to primary!'"
# because we want to check those interfaces and if they go down trigger a state change
# note the expression "!" indicating "not"
if ! ( $pingCheck1 && $pingCheck2 ) {
# so, if both fail change state
set-state backup

state backup {
init {
# when this state initializes run the script to add those alias IPs
run "/path/to/script/changetobackup.sh 'Changing state to backup!'"
# continue to evaluate those interfaces in case they return
if ( $pingCheck1 && $pingCheck2 ) {
# I had to remove those aliases here because when I had it run during the primary
# state's init{} it would throw errors and crash when starting up because those aliases
# don't exist when the daemon starts. This could be solved with a third state, but I didn't require that.
run "/path/to/script/changetorprimary.sh 'Reverting to Primary State from Backup State!'"
set-state primary

this does a ping on the primary IPs on my master router's dc0 and dc1 interfaces and, if it can't hit them, changes state to backup. When the primary state initializes it simply echoes the state. After the evaluation fails, and the state changes to backup, it executes a script that contains a list of alias IPs to add to the slave's NIC. Also during this backup state the evaluation continues. If it can hit both interfaces on the master router it executes a script to remove those alias IPs added in the "changetobackup.sh"
script prior to resuming the primary state. This file is highly customizable - google it and you'll find many examples illustrating how you can do different things here.

So that's my how-to. While there are other means of accomplishing what I've done, I found that
this method is accessible to both hardened BSD veterans as well as those relatively new to the
environment. Additionally be aware that this is by no means the limit of ifstated, which has the
capability to perform all sorts of evaluations and trigger events (scripts/commands/etc) when
they occur.

My hardware for the FreeBSD routers were identical Dell Power Edge 2300 servers with 4-port DLink
cards and 1 GB RAM each. Each server routes traffic at a rate of approximately 45 Mbps with very
low load. In the future I plan to evaluate the same system on the 64-bit release of FreeBSD.
Reply With Quote

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Lagg failover on FreeBSD 7.0 Dell 1950/Broadcom 5708 NICs rfranzke FreeBSD General 4 14th September 2010 08:06 PM
Best way to check if freebsd server is running a nameserver service/daemon Yuka FreeBSD General 7 6th November 2008 01:26 AM
Running Pure 64-Bits On FreeBSD. MetalHead FreeBSD General 4 21st October 2008 04:59 AM
Decision for FreeBSD router bichumo General software and network 3 3rd July 2008 07:33 PM
Router - recommendations for FreeBSD? ClaptonOrient FreeBSD General 17 12th June 2008 06:12 PM

All times are GMT. The time now is 09:50 PM.

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content copyright © 2007-2010, the authors
Daemon image copyright ©1988, Marshall Kirk McKusick