Architecture
FBOSS is a collection of cooperating daemons on the switch's x86 CPU, each owning one part of the hardware and each exposing a Thrift API. This page describes the processes, how they talk to each other, the agent's internal layers (SwSwitch, SwitchState, HwSwitch, the SAI layer), the two agent run modes, and the default ports and state directories you will meet when operating or debugging a switch.
The Services on a Switch
| Service | Binary | Owns | Default Thrift port |
|---|---|---|---|
| Agent (software side) | fboss_sw_agent (split) or wedge_agent-sai_impl (mono) |
Control plane and switch state: ports, VLANs, interfaces, routes, neighbors, ACLs, QoS, LLDP, LACP | 5909 (--port) |
| Hardware agent | fboss_hw_agent-sai_impl, one per ASIC (fboss_hw_agent@N) |
Programming one ASIC through SAI | 5931 + switch index (DEFAULT_HW_CTRL_BASE_PORT) |
| QSFP service | qsfp_service |
Transceivers and external PHYs | 5910 (--port) |
| FSDB | fsdb |
Central publish/subscribe store for state and stats | 5908 (--fsdbPort) |
| LED service | led_service |
Front-panel port LEDs | 5930 (--led_service_port) |
| Sensor service | sensor_service |
Temperature, voltage, current, power sensors | 5970 (--thrift_port) |
| Data corral service | data_corral_service |
FRU presence detection and presence LEDs | 5971 (--thrift_port) |
| Fan service | fan_service |
Thermal control (fan PWM) | 5972 (--thrift_port) |
| Rackmon | rackmon |
Rack power monitoring | 5973 (--port) |
| Platform manager | platform_manager |
Platform discovery, BSP kernel modules, stable device paths | 5975 (--thrift_port, daemon mode only) |
Several default ports collide with VNC (59xx). The code already defines replacement flags, --migrated_port (5959) for the agent, --migrated_port (5960) for qsfp_service, and --migrated_fsdbPort (5958) for FSDB, noting a future migration. The hardware agent also reaches the software agent through --swswitch_port, whose default is 5959.
The CLI tools are clients of these services: fboss2 connects to the agent, qsfp_service, and FSDB (with --agent-port, --qsfp-port, --fsdb-port to override), wedge_qsfp_util talks to qsfp_service or directly to transceivers, and diag_shell_client opens the SAI diag shell on a hardware agent (port 5931 by default).
How the Services Relate
+----------------------------------+
| FSDB |
| state + stats, pub/sub (5908) |
+----------------------------------+
^ publish ^ publish ^ subscribe
| | |
+------------------+ +---------------+ +---------------+ +-------------+
| platform_manager | | Agent | | qsfp_service | | fan_service |
| (boot, kmods, | | SwSwitch |<->| optics, PHYs | | (reads |
| device paths) | | (5909) | | (5910) | | sensors) |
+------------------+ +-------+-------+ +---------------+ +-------------+
| state deltas (Thrift streams in split mode)
+-------v-------+
| HW agent(s) | [email protected] (5931+N)
| SaiSwitch |
+-------+-------+
| SAI API calls
+-------v-------+
| Vendor SAI + |
| vendor SDK |
+-------+-------+
v
Switch ASIC
- Boot order.
platform_managerruns first. It identifies the platform, installs and loads the BSP kernel modules, and creates stable symlinks to devices, so every other service finds sensors, FPGAs, and transceivers at fixed paths. See Platform Services. - Agent and qsfp_service cooperate on every port: the agent owns the ASIC side (SerDes, MAC, forwarding),
qsfp_serviceowns the optic and any external PHY. Both use the same platform mapping. - FSDB collects state and stats from publishers (agent,
qsfp_service, sensors) and serves subscribers on and off the box.fan_servicecan consume sensor and optics data to drive fan speed.
Inside the Agent
The agent's design is built around three abstractions described in fboss/agent/doc/Overview.md:
- SwitchState: an in-memory, copy-on-write (COW) tree that describes the entire configuration and operational state of the switch. It contains everything needed to decide how any packet should be handled. Changes never mutate a published state; they produce a new state, so readers always see a consistent snapshot.
- SwSwitch: the hardware-independent logic, effectively a software-only switch. It holds the current
SwitchState, applies configuration, runs control-plane protocols (ARP, NDP, LLDP, LACP, DHCP relay), and processes packets trapped to the CPU. - HwSwitch: the hardware abstraction layer. Its central method,
stateChanged(), receives aStateDelta(old and newSwitchState) and must make the hardware match the new state. The interface deliberately expects little: if the hardware cannot accelerate some configuration, it may trap packets to software and let SwSwitch handle them.
The current implementation adds more layers between SwSwitch and the ASIC:
| Layer | Role |
|---|---|
| Thrift handler layer | Exposes the FbossCtrl API (used by CLIs and route programmers), MultiSwitchCtrl (used by hardware agents in split mode), and test APIs. |
| Core logic | Feature managers inside SwSwitch: RIB (routing information base), neighbor updater (ARP/NDP caches), port handling, ACLs, LLDP manager, link aggregation, mirroring, and more. |
SwitchState (COW) |
The single source of truth, updated by config application and protocol events. |
MultiHwSwitchHandler |
Fans state deltas out to one or more hardware switches. |
HwSwitchHandler / HW agent |
Receives deltas and turns them into hardware programming; reports events back (link changes, FDB/L2 learning, received packets). |
SaiSwitch |
The HwSwitch implementation on top of SAI, with a SaiManagerTable of per-object managers (ports, routes, neighbors, ACLs, queues, ...). |
| SAI API wrappers and object store | Type-safe C++ wrappers (SaiAttribute, SaiApi) around the C SAI API, and RAII, reference-counted storage of SAI objects. The store is also what makes warm boot work: SAI object state is serialized and reloaded. |
| Vendor SAI and SDK | The vendor's libsai_impl, linked into the hardware agent at build time (or fake SAI). |
Warm Boot vs Cold Boot
On a cold boot the agent initializes the ASIC from scratch. On a warm boot it restores its SwitchState and the SAI adapter state from files and reconciles hardware without disrupting forwarding. The warm boot artifacts live in the volatile state directory (/dev/shm/fboss/warm_boot/), for example sai_adaptor_state_0, switch_state_0, and thrift_switch_state, and a flag file /dev/shm/fboss/warm_boot/can_warm_boot (with a _<switchIndex> suffix per hardware agent) records whether the next start may warm boot. Every start is recorded in /var/facebook/logs/fboss/fboss_sw_agent_boot_history.log as Start of a WARM_BOOT or Start of a COLD_BOOT. Because /dev/shm is cleared on reboot, a switch reboot always results in a cold boot.
Mono vs multi_switch (Split) Mode
The agent runs in one of two modes, selected by the --multi_switch flag (default false), usually set through defaultCommandLineArgs in the agent config ("multi_switch": "true"):
mono |
multi_switch (split) |
|
|---|---|---|
| Processes | One: wedge_agent-sai_impl |
fboss_sw_agent plus one fboss_hw_agent-sai_impl per ASIC (fboss_hw_agent@0, @1, ...) |
| SW to HW communication | Direct function calls | Thrift streams over MultiSwitchCtrl: state deltas (OperDelta) down, event sinks (link changes, FDB events, RX packets) up |
| Failure isolation | A crash takes everything down | Hardware agents can restart separately |
| Status | Deprecated in the test harness, "will be removed in the future" | Production model, the default for agent tests |
fboss2 show hw-agent reports, per hardware agent, whether each stream is in sync and how many events were sent and received. In split mode, fboss_hw_agent needs IPv6 to reach the software agent at ::1: the Quick Start explains why containers need an IPv6-enabled network.
How a Configuration Change Flows
- The agent reads
/etc/coop/agent.confat start-up (see Agent Configuration), or re-reads it on a reload request. ApplyThriftConfigturns theSwitchConfiginto a newSwitchState.- SwSwitch computes the
StateDeltabetween the old and new state. - The delta goes to each hardware agent (directly in mono mode, as an
OperDeltaover Thrift in split mode). SaiSwitchwalks the delta and calls the per-object SAI managers, which issue SAI create, set, and remove calls.- If the hardware rejects an update, the agent dumps the offending states to
/var/facebook/fboss/crash/bad_update/old_stateandnew_statefor analysis.
Route programming follows the same path: an external routing daemon calls the agent's Thrift API, the RIB computes the FIB, and the resulting SwitchState change flows down as a delta. The open source repo contains no general routing daemon; fboss/agent/tools/ has small sample scripts, and BGP support in the CLI is still being upstreamed.
State and Log Locations
| Path | Contents | Flag |
|---|---|---|
/etc/coop/agent.conf |
Agent startup config | --config |
/etc/coop/qsfp.conf |
qsfp_service config |
--qsfp_config |
/etc/coop/led.conf |
LED service config | --led_config |
/etc/coop/fsdb/current |
FSDB config | --fsdb_config |
/dev/shm/fboss |
Volatile state (warm boot files) | --volatile_state_dir |
/var/facebook/fboss |
Persistent state, crash dumps, fruid.json, platform_name cache |
--persistent_state_dir |
/dev/shm/fboss/qsfp_service |
qsfp_service volatile state (cold boot flag) |
--qsfp_service_volatile_dir |
/var/facebook/logs/fboss/ |
Service logs, boot history, state snapshots |