There are many articles on BFD. It is well known that BFD has the following advantages over routing protocol hellos/keepalives:
- BFD is more light weight than hellos/keepalives.
- Multiple clients can register to BFD instead of configuring each protocol with aggressive timers.
- On some platforms, BFD can be offloaded to the hardware instead of the CPU.
- BFD provides faster timers than routing protocols.
- BFD is less CPU intensive.
What does light weight mean, though? Does it mean that the packets are smaller? Let’s compare a BFD packet to an OSPF Hello. Starting with the OSPF Hello:
Frame 269: 114 bytes on wire (912 bits), 114 bytes captured (912 bits) on interface ens192, id 1 Ethernet II, Src: 00:50:56:ad:8d:3c, Dst: 01:00:5e:00:00:05 Internet Protocol Version 4, Src: 203.0.113.0, Dst: 224.0.0.5 Open Shortest Path First OSPF Header Version: 2 Message Type: Hello Packet (1) Packet Length: 48 Source OSPF Router: 192.168.128.223 Area ID: 0.0.0.0 (Backbone) Checksum: 0x7193 [correct] Auth Type: Null (0) Auth Data (none): 0000000000000000 OSPF Hello Packet OSPF LLS Data Block
There’s 114 bytes on the wire consisting of:
- 20 bytes of IP.
- 14 bytes of Ethernet.
- 80 bytes of OSPF whereof:
- 24 bytes OSPF header.
- 24 bytes OSPF Hello.
- 32 bytes of data (TLVs etc.).
OSPF does not rely on TCP or UDP so only IP and Ethernet are needed. Now let’s compare this to BFD:
Frame 56: 66 bytes on wire (528 bits), 66 bytes captured (528 bits) on interface ens192, id 1 Ethernet II, Src: 00:50:56:ad:8d:3c, Dst: 00:50:56:ad:e6:ab Internet Protocol Version 4, Src: 203.0.113.0, Dst: 203.0.113.1 User Datagram Protocol, Src Port: 49152, Dst Port: 3784 BFD Control message 001. .... = Protocol Version: 1 ...0 0000 = Diagnostic Code: No Diagnostic (0x00) 11.. .... = Session State: Up (0x3) Message Flags: 0xc0 Detect Time Multiplier: 3 (= 3000 ms Detection time) Message Length: 24 bytes My Discriminator: 0x00001001 Your Discriminator: 0x00001001 Desired Min TX Interval: 1000 ms (1000000 us) Required Min RX Interval: 1000 ms (1000000 us) Required Min Echo Interval: 500 ms (500000 us)
There’s 66 bytes on the wire consisting of:
- 20 bytes of IP.
- 14 bytes of Ethernet.
- 8 bytes of UDP.
- 24 bytes of BFD.
BFD is very efficient. 24 bytes compared to 80 bytes of OSPF. It does require UDP, though, so in essence it’s 32 bytes vs 80 bytes, which is still quite the difference. In total, every packet is 66 bytes instead of 114. In general, it should be faster to process a smaller amount of data than a larger amount. This does not explain why BFD is light weight and more efficient than Hellos in OSPF, or any other protocol, though. BFD does one thing and does it well. It’s sole purpose is to verify liveliness. Compare this to for example OSPF Hellos where Hellos are used to both build adjacencies and verify liveliness. Like my dear friend Peter PalĂșch said, BFD can be compared to some tools in the Linux/Unix world where the tool has one specific use and does it very well. When you expand the use cases, you decrease the efficiency. Reading RFC 2328, for every OSPF packet received the router has to do the following:
- Verify the IP checksum.
- Verify that destination IP is the IP of receiving interface or ALLSPFRouters or AllDRouters.
- Verify that IP protocol is 89 (OSPF).
- Verify that packet was not locally originated (or the packet could be a multicast packet that the router generated).
Then the OSPF header must be checked:
- Verify that version is set to 2.
- Verify the Area ID.
- Only accept packets to AllDRouters if receiving interface is DR or BDR.
- Verify that authentication type matches.
- Authenticate the packet.
It doesn’t stop there. For OSPF Hellos there are also the following considerations:
- Verify network mask (depending on network type).
- Verify hello and dead interval.
- Verify ExternalRoutingCapability bit (if area is stub or not).
- Verify source of packet to one of the receiving interface’s neighbors.
- Set neighbor structure’s Neighbor ID equal to Router ID.
- Generate events to be given to neighbor and interface state machines.
There is a lot going on here. There are many checks and several state machines that need to be updated. When sending OSPF Hellos for example every 10 seconds, this is not going to tax the CPU much as the packets are so infrequent. Below is a Catalyst8000v using the default timers of 10/40:
BFD1#show processes cpu | i Hello 555 428 5715 74 0.00% 0.00% 0.00% 0 OSPF-1 Hello
What happens if we set it to something much more aggressive?
BFD1(config-if)#ip ospf dead-interval ? <1-65535> Seconds minimal Set to 1 second BFD1(config-if)#ip ospf dead-interval minimal hello-multiplier 10
With this configuration, Hellos are sent every 100ms. CPU load does go up a bit:
BFD1#show processes cpu | i Hello 555 319 4241 75 0.31% 0.19% 0.06% 0 OSPF-1 Hello BFD1#show processes cpu | i Hello 555 324 4312 75 0.39% 0.20% 0.07% 0 OSPF-1 Hello BFD1#show processes cpu | i Hello 555 326 4379 74 0.39% 0.20% 0.07% 0 OSPF-1 Hello
This is still a small amount but keep in mind that this is a virtual platform and with a single OSPF neighbor. If there were a lot of neighbors this would start to add up.
Now just for fun let’s do the same with BFD, send a packet every 100ms:
BFD1(config)#int gi2 BFD1(config-if)#bfd interval 100 min_rx 100 multiplier 10
The load on the CPU is minimal:
BFD1#show processes cpu | i BFD 153 0 1 0 0.00% 0.00% 0.00% 0 BFD HW EVENT 154 0 1 0 0.00% 0.00% 0.00% 0 BFD IPV6 ADDR CH 164 1 62 16 0.00% 0.00% 0.00% 0 BFD 348 1 3 333 0.00% 0.00% 0.00% 0 BFD HA 453 0 3 0 0.00% 0.00% 0.00% 0 BFD events 564 0 11 0 0.00% 0.00% 0.00% 0 BFD debugs 565 1 19 52 0.00% 0.00% 0.00% 0 BFD packet stats
Now, this is by no means a very empiric test. Your results will vary depending on platform. Still, it’s quite evident that processing OSPF packets do consume more CPU than BFD does. The benefit of BFD is also that multiple protocols can register with it.
BFD is a well known protocol by now, but not many articles talk about the aspects that make BFD more light weight than routing protocol hellos. I hope you have learned something new from this post and a big thank you to my dear friend Peter PalĂșch for helping me with the research on this topic.
Thanks for the insight, Daniel. Very informative!
Thanks, Chris!
Previously, the common belief was that BFD (at least in my understanding) is primarily offloaded in hardware, making it a preferable option over fine-tuning routing protocols.
I have always been confused since there is an option to offload it in HW on the ASR9k…
However, your insights show that while it can be processed in the CPU, it remains lightweight.
Very interesting, thanks Daniel !
Thanks, Mehdi!
One key aspect you have missed is that BFD is implemented in most interface silicon/ASICs on router/switches. As such it requires no CPU cycles generate the packets and framing, and can scale to hundreds of interfaces at sub-second intervals.
Its my understanding that for software routers because BFD is generating fixed size packets with limited change for actions, the memory interaction is much more efficient. Consider that building an OSPF hello requires many calculations for the data and then to be formatted and moved to the NIC memory. Its been a while since I followed this area, might need revalidation on this.
Right, I did mention that some platforms do hardware offloading. That is well known. The focus of the post was to describe that efficiency is achieved as BFD has a single purpose as opposed to the Hello of a routing protocol.
I don’t know enough about the code to know what is possible to offload in OSPF or not. It probably varies per platform. Routers like the Catalyst 8200/8300 has QFP which is some fancy form of processor, but it does support BFD offloading.
Great write-up, thank you!
Thank you, Bryan!
Thank you Daniel for this insightful explanation on BFD.
Keep up the good works.
Thank you!
Thanks for sharing.
Keep up the good works.
Thanks!