I am coding OSPF support for the FireBricks now - and making some slow headway. So far all I have working is hello packets with DR and backup router election, dead router timeouts, and authentication. Given that this covers the general packet receipt processing and generation, it is quite a bit of progress even if it sounds like very little.
I have my head around the concepts of OSPF, but working through the mechanics is taking a while. The problem is that it is so different to BGP.
Normal routing within a router (OSPF or BGP) works on routes existing in a set in the device, with most specific always being picked for any destination. I.e. if you have a route for 10.0.0.0/8 (That is 10.0.0.0 to 10.255.255.255) and also a route for 10.2.3.0/24 (That is 10.2.3.0 to 10.2.3.255) then if a packet is being sent to 10.2.3.4 you send to the latter (most specific) route.
Where a router has more than one route to the same prefix (e.g. two separate routes for 10.2.3.0/24) then some process decides which is best. The actual sending of packets (the forwarding plane) does not need to know of the other, worse choice, routes - only the one it has to use (the best choice). The other routes still exist in the routing table though, so if the best route is removed, the next best takes its place.
There are however two means of sharing routes with other routers. OSPF and BGP are examples of these two main concepts, and they work very differently.
BGP works by telling peers (connected neighbouring routers) what routes it is using. I.e. what are those best choices it has made for each prefix. The protocol ensures that changes to this set of best choices are sent as they happen. The router receiving these includes them in its routing table, and still makes its best choice from all the routes it has, and its one best choice is what it tells its neighbours. One of the criteria for making the choice is how many systems the route has come through, and this allows the best overall path to be used for packets through many routers (e.g. across the Internet).
There is a big downside that if a link fails then all of the routes learned by that link have to be removed (perhaps leaving next best choices or removing routes all together). When the link comes back, all those have to be sent again. The knock on effect of changes to best choice will then be sent to neighbours, and spread around the Internet. Where a pair of routers exist, and so routes are passed on by both, the best choice one step removed is not a change, and so the ripples do not spread far. When multiple links fails so a route is totally removed, the effect is an update sent to the whole of the Internet!
However, each router only has the set of routes it knows itself and got from its immediate neighbours. It does not really need to know about anything further away. Its neighbours have already made the best choice decision on each route and passed on that final choice. As you get further from the source of a route, the best choice becomes less prone to change and so less necessary to pass on as a change.
This works well on the Internet, and is what is done between ISPs. One router knowing all routes held by all routers in the Internet would be somewhat difficult. Even the way BGP works the full table is over 400,000 routes now, and you get that from each transit provider with which you peer.
OSPF works differently, and its design is more suited to smaller networks generally. It works by every route known by every router in an area being known to every other router. This is potentially a lot more data, but if you are only using it to define the network, even one of a reasonable size ISP, it is not that daft. Often OSPF is used to ensure all devices in a network can see each other and then BGP is used to send the external Internet routes around the network.
OSPF therefore has to pass on all of this routing information. Each router is also told the topology of the network - routers and networks and links. This means that the path to send a packet can be worked out for the topology using Shortest Path First. The still boils down to each prefix having a place to go (the target for the first hop on the shortest path), though OSPF does throw in a complication of allowing equal paths to imply load balancing of traffic over more than one route.
The key difference here is that if topology changes, e.g. a link fails, then this is a small update to all routers to ensure that they all know the new topology and can decide on new shortest paths. The actual routes visible do not have to change or be re-sent. It is a bit of a trade off, as every router has to know more in the first place, but it makes the configuration of quite complex networks very simple.
To add to the simplicity, OSPF is usually something you just turn on on a router and it just works. There are settings and even security you can configure, but routers discover their neighbours automatically with multicast packets. This means you don't have to tell the routers the network topology - they work it out for themselves.
This is a lot simpler than BGP - though there is nothing in principle to stop BGP having such a discovery protocol, it does not normally, and requires manual configuration. The difference also reflects the typical usage - BGP used between ISPs and carefully and manually configured - often associated with a physical link being set up and even contracts signed. OSPF is used within a network and so just works with all of the devices that get connected in the network.
For FireBrick, the main use of OSPF is allowing the FireBrick to take part in this simple OSPF set up and to inject routes when used to connect people by L2TP or tunnels or VPNs so that the rest of the network just knows where to send traffic. It makes some sense.
Hopefully not a lot more work to do - it is a big learning exercise for me to understand the different conceptual model of OSPF and how to integrate in to the routing system in the FireBrick - but this is what makes coding fun.
Oh, and obviously coding OSPFv2 (IPv4) and OSPFv3 (IPv6) at the same time here.