Skip to content

[bfdsyncd]: BFD hardware offload for BGP sessions - #4588

Draft
vaishnav-nexthop wants to merge 1 commit into
sonic-net:masterfrom
vaishnav-nexthop:nexthop.bfd-hw-offload
Draft

[bfdsyncd]: BFD hardware offload for BGP sessions#4588
vaishnav-nexthop wants to merge 1 commit into
sonic-net:masterfrom
vaishnav-nexthop:nexthop.bfd-hw-offload

Conversation

@vaishnav-nexthop

Copy link
Copy Markdown

What I did

Add a new bfdsyncd daemon that bridges FRR's bfdd to BfdOrch via APP_DB, so BGP BFD sessions can run entirely on the ASIC instead of in software.

End-to-end split:

FRR bfdd  --BFDDP/TCP-->  bfdsyncd  --APP_DB-->  BfdOrch  --SAI-->  ASIC
(state machine,           (this PR,              (already in       (probes
 user space)               bgp container)         swss container)   on wire)
  • bfdsyncd/ — new daemon. Built here in swss but runs in the bgp container alongside FRR. Opens the BFDDP control channel (FRR's bfdd is launched with --dplaneaddr ipv4c:127.0.0.1 so it talks to bfdsyncd over BFDDP/TCP on 127.0.0.1). Parses BFD_DP_SESSION_ADD / DELETE / UPDATE messages and translates them into APP_BFD_SESSION_TABLE writes. Pushes BFD state transitions from STATE_DB back to bfdd. Warm-restart aware via the existing warmRestartHelper.
  • orchagent/bfdorch.cpp. On a state change, read the SAI remote-side attrs (REMOTE_DISCRIMINATOR, REMOTE_MULTIPLIER, REMOTE_MIN_RX, REMOTE_MIN_TX) and surface them in STATE_DB so the operator can see negotiated timers. create_bfd_session() now treats a re-create on an existing key as an attribute update (set_bfd_session_attribute) instead of a hard error, so bfdd can retune timers without bringing the session down. A missing bfd_session_lookup entry at state-change time logs and continues instead of dereferencing.
  • BgpGlobalStateOrch. The SYSTEM_DEFAULTS|software_bfd override is surfaced at WARN with a detailed message so operators see when the override is actually taking effect.
  • tests/mock_tests/bfdsyncd/test_bfdlink.cpp — gtest coverage for BFDDP frame parsing, key composition, and APP_DB writes.

Why I did it

Hardware-offloaded BFD lets the ASIC drive BFD probes on the wire instead of FRR's bfdd doing it from user space. Offloading the session to hardware removes the per-session CPU/jitter cost and is what makes sub-second timers (down to ~300 ms) actually viable across a large BGP neighbor count.

How I verified it

  • Unit tests: make check (target tests_bfdsyncd) — 8/8 pass on both bookworm (GCC 13) and trixie (GCC 14.2) sonic-slave images.
  • On hardware (Broadcom DNX):
    1. Brought up two BGP neighbors with BFD enabled on a routed link.
    2. Programmed BFD_SESSION_TABLE with min_tx=300 min_rx=300 multiplier=3.
    3. Confirmed session in ASIC_DB: SAI_BFD_SESSION_ATTR_HW_LOOKUP_VALID=true, MIN_TX/MIN_RX=300000, MULTIPLIER=3.
    4. Link flap → session declared Down within multiplier × min_rx ≈ 900 ms.
    5. Renegotiating timers (push min_rx=500) does not tear down the session — syncd log shows set_bfd_session_attribute only, no delete_bfd_session / create_bfd_session pair.

Details if related

  • bfdsyncd runs in the bgp container; FRR bfdd needs --dplaneaddr ipv4c:127.0.0.1 to use it. The corresponding supervisord template change (gating bfdsyncd off when SYSTEM_DEFAULTS|software_bfd=enabled) lives in sonic-buildimage (dockers/docker-fpm-frr/).
  • The header bfdsyncd/bfdd/bfddp_packet.h is FRR's BFDDP wire-protocol definition (NetDEF, MIT-style license) included verbatim so we don't take a FRR build-time dependency just for the message layout.
  • Filed as a draft while the matching sonic-buildimage and sonic-mgmt changes are being prepared.

Add a new bfdsyncd daemon that bridges FRR's bfdd to BfdOrch via APP_DB,
enabling BGP BFD sessions to run entirely on the ASIC instead of in
software.  Offloading the session to hardware removes the per-session
CPU/jitter cost and is what makes sub-second timers (down to ~300 ms)
viable across a large BGP neighbor count.

End-to-end split:

    FRR bfdd  --BFDDP/TCP--> bfdsyncd --APP_DB--> BfdOrch --SAI--> ASIC
    (state machine,          (this PR,            (already in     (probes
     user space)              bgp container)       swss container) on wire)

bfdd keeps the BFD state machine and protocol logic; bfdsyncd is the
BFDDP<->Redis bridge; BfdOrch is the Redis<->SAI bridge.

bfdsyncd/ -- new daemon, runs in the bgp container alongside FRR
  (bfdd is launched with --dplaneaddr ipv4c:127.0.0.1 so it talks
  to bfdsyncd over BFDDP/TCP on 127.0.0.1).  Opens the BFDDP control
  channel, parses BFD_DP_SESSION_ADD / DELETE / UPDATE messages, and
  translates them into APP_BFD_SESSION_TABLE writes.  Reads back state
  transitions from STATE_DB and pushes them to bfdd.  Warm-restart
  aware via the existing warmRestartHelper.

orchagent/bfdorch.cpp -- on a BFD session state change, read the
  remote-side SAI attrs (REMOTE_DISCRIMINATOR, REMOTE_MULTIPLIER,
  REMOTE_MIN_RX, REMOTE_MIN_TX) and surface them in STATE_DB so the
  operator can see negotiated timers.  create_bfd_session() now treats
  a re-create on an existing key as an attribute update
  (set_bfd_session_attribute) instead of a hard error, which lets bfdd
  retune timers without bringing the session down.  A missing
  bfd_session_lookup entry at state-change time logs and continues
  instead of dereferencing.

BgpGlobalStateOrch -- the SYSTEM_DEFAULTS|software_bfd override is now
  surfaced at WARN with a detailed message so operators see when the
  override is actually taking effect.

tests/mock_tests/bfdsyncd/test_bfdlink.cpp -- gtest coverage for
  BFDDP frame parsing, key composition, and APP_DB writes.

How verified:

* Unit tests: `make check` (tests_bfdsyncd: 8/8 pass) on both bookworm
  (GCC 13) and trixie (GCC 14.2) slave images.
* Hardware (Broadcom DNX): brought up BGP neighbors with BFD enabled,
  set min_tx=300 min_rx=300 multiplier=3 in BFD_SESSION_TABLE.
  Confirmed session in ASIC_DB with SAI_BFD_SESSION_ATTR_HW_LOOKUP_VALID
  true, MIN_TX/MIN_RX=300000, MULTIPLIER=3.  Link flap declares Down
  within multiplier x min_rx ~= 900 ms.  Renegotiating timers (push
  min_rx=500) does not bring the session down -- syncd log shows
  set_bfd_session_attribute, not delete + create.

Signed-off-by: vaishnav-nexthop <vaishnav@nexthop.ai>
@linux-foundation-easycla

Copy link
Copy Markdown

CLA Not Signed

@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@balajib-cisco

Copy link
Copy Markdown

Hi,
Why are you raising this PR which is exact copy of #4253 ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants