This guide shows how to set up bidirectional forwarding detection (BFD) between an Oxide rack and an upstream network appliance. The BFD setup this guide will go over is depicted below. The firewall represents a logical entity in your network and may actually be several individual entities in an HA configuration.
Background
The BFD protocol is used to determine if two hosts can communicate over a specified set of addresses. Checks are performed continuously through an exchange of control packets between BFD peers at a configurable frequency. BFD is based on a state machine model. Control messages from peers and internal timers determine transitions between states.
On the Oxide platform, BFD is integrated with static routing. This means that administrators can configure BFD to monitor static route nexthops for a given rack switch. If BFD determines that a nexthop for a route becomes unreachable, that route will be removed from the switch. In order to work in both directions, BFD sessions that are peered with an Oxide rack must also be integrated with static routing in a similar way.
BFD Mode
The Oxide platform supports two BFD modes.
Single-hop mode (RFC 5881)
Multi-hop mode (RFC 5883)
Single-hop mode works for peers one layer-3 hop apart, and operates over the
destination port 3784
with a source port in the range 49152-65535
.
Multi-hop mode works for peers multiple hops apart, and operates over the
destination port 4784
. Both the single-hop and multi-hop modes run over UDP.
Peers must be operating in the same mode to establish a BFD session.
Configuration
The rest of the guide will go through configuring BFD on the system depicted in the diagram above.
First inspect the routes that are present on the Oxide rack.
for i in {0..3}
do
oxide system networking switch-port-settings view --port default-uplink$i \
| jq -r '.routes[] | "\(.dst) → \(.gw)" '
done
This shows the following.
0.0.0.0/0 → 198.51.101.1/32
0.0.0.0/0 → 198.51.101.9/32
0.0.0.0/0 → 198.51.101.5/32
0.0.0.0/0 → 198.51.101.13/32
We’ll be setting up a BFD session for each of these nexthops. To check the current BFD status of the Oxide rack, use the following command.
oxide system networking bfd status
This returns an empty array, indicating no BFD sessions are configured.
[]
To set up a BFD session for the first route in the list above, do the following.
oxide system networking bfd enable \
--required-rx 1000000 \
--detection-threshold 3 \
--remote 198.51.101.1 \
--mode single_hop \
--switch switch0
The required-rx
argument indicates the interval at which the rack expects to
receive BFD control messages from its peer (in microseconds), and the rate at
which it will send control messages to the peer. The detection-threshold
argument indicates how many required receive intervals may be missed before a
session is considered down. The remote
argument specifies the remote host to
establish a BFD session with. The mode
argument is either single_hop
or
multi_hop
and indicates the BFD mode as described in the background section
above. The switch
argument identifies which rack switch this BFD session will
run on, the value is either switch0
or switch1
.
After running this command check the status of the BFD session.
oxide system networking bfd status
[
{
"detection_threshold": 3,
"local": "0.0.0.0",
"mode": "single_hop",
"peer": "198.51.101.1",
"required_rx": 1000000,
"state": "up",
"switch": "switch0"
}
]
The up
value for state
indicates that the rack has successfully established a
BFD session with 198.51.101.1
.
If we continue for the remaining addresses, we see the following
[
{
"detection_threshold": 3,
"local": "0.0.0.0",
"mode": "single_hop",
"peer": "198.51.101.9",
"required_rx": 1000000,
"state": "up",
"switch": "switch0"
},
{
"detection_threshold": 3,
"local": "0.0.0.0",
"mode": "single_hop",
"peer": "198.51.101.1",
"required_rx": 1000000,
"state": "up",
"switch": "switch0"
},
{
"detection_threshold": 3,
"local": "0.0.0.0",
"mode": "single_hop",
"peer": "198.51.101.5",
"required_rx": 1000000,
"state": "up",
"switch": "switch1"
},
{
"detection_threshold": 3,
"local": "0.0.0.0",
"mode": "single_hop",
"peer": "198.51.101.13",
"required_rx": 1000000,
"state": "up",
"switch": "switch1"
}
]
In the event that the first link goes down, the
oxide system networking bfd status
looks as follows.
[
{
"detection_threshold": 3,
"local": "0.0.0.0",
"mode": "single_hop",
"peer": "198.51.101.9",
"required_rx": 1000000,
"state": "up",
"switch": "switch0"
},
{
"detection_threshold": 3,
"local": "0.0.0.0",
"mode": "single_hop",
"peer": "198.51.101.1",
"required_rx": 1000000,
"state": "down",
"switch": "switch0"
},
{
"detection_threshold": 3,
"local": "0.0.0.0",
"mode": "single_hop",
"peer": "198.51.101.5",
"required_rx": 1000000,
"state": "up",
"switch": "switch1"
},
{
"detection_threshold": 3,
"local": "0.0.0.0",
"mode": "single_hop",
"peer": "198.51.101.13",
"required_rx": 1000000,
"state": "up",
"switch": "switch1"
}
]
In the event that all BFD sessions go down, routing behavior reverts to function as if no BFD configuration is present, considering each nexthop equally bad and performing ECMP over each. As soon as any subset of the configured BFD sessions is restored, only the routes associated with that subset will be used.