Commit b746e39ff3 for frr
commit b746e39ff3eabcfbe01850f17956b15ac6557722
Author: Sougata Barik <sougatab@nvidia.com>
Date: Tue Aug 4 06:07:53 2026 +0530
lib: LTTng trace for deferred link-local BFD session install
Adds observability for the #5131052 fix path: _bfd_sess_valid() defers
the install of a single-hop IPv6 link-local BFD session when its outgoing
interface is not yet known. Each deferral is now visible on the
frr_libfrr:bfd_sess_defer_linklocal_without_intf tracepoint, which tells
us exactly which session and VRF is being held back and how often, before
it later installs with a unique per-interface key.
Files:
lib/libfrr_trace.h : new TRACEPOINT_EVENT for the defer event
(fields: bsp_ptr, vrf_id, family, dst, src).
lib/bfd.c : #include "libfrr_trace.h" and the matching
frrtrace() call inside _bfd_sess_valid().
tools/frr_babeltrace.py : parser for the new event.
No functional change; the tracepoint degrades to (void)0 when HAVE_LTTNG
is not compiled in. Building the fix-path tracepoint requires the usual
opt-in configure flag ('./configure --enable-lttng') documented in
doc/developer/tracing.rst. The stock upstream .deb build is not modified
and remains LTTng-off.
Ticket: #5131052
Signed-off-by: Sougata Barik <sougatab@nvidia.com>
diff --git a/lib/bfd.c b/lib/bfd.c
index f67e69c7ad..d2e4b2f0de 100644
--- a/lib/bfd.c
+++ b/lib/bfd.c
@@ -20,6 +20,7 @@
#include "lib/json.h"
#include "bfd.h"
#include "bfdd/bfd.h"
+#include "libfrr_trace.h"
DEFINE_MTYPE_STATIC(LIB, BFD_INFO, "BFD info");
DEFINE_MTYPE_STATIC(LIB, BFD_SOURCE, "BFD source cache");
@@ -478,6 +479,10 @@ static bool _bfd_sess_valid(const struct bfd_session_params *bsp)
if (!bsp->args.mhop && bsp->args.family == AF_INET6 &&
IN6_IS_ADDR_LINKLOCAL(&bsp->args.dst) &&
bsp->args.ifnamelen == 0) {
+ frrtrace(5, frr_libfrr, bfd_sess_defer_linklocal_without_intf,
+ (void *)bsp, (uint32_t)bsp->args.vrf_id,
+ (uint8_t)bsp->args.family,
+ &bsp->args.dst, &bsp->args.src);
if (bsglobal.debugging)
zlog_debug("%s: single-hop link-local session without interface; deferring install",
__func__);
diff --git a/lib/libfrr_trace.h b/lib/libfrr_trace.h
index 62a4034aa5..ddad49cda6 100644
--- a/lib/libfrr_trace.h
+++ b/lib/libfrr_trace.h
@@ -28,6 +28,38 @@
/* clang-format off */
+/*
+ * Fired by _bfd_sess_valid() (lib/bfd.c) when a single-hop IPv6 link-local
+ * BFD session is deferred because its outgoing interface is not yet known
+ * (the #5131052 fix). One event per deferral tells us exactly which session
+ * is being held back and how often, before it later installs with a unique
+ * per-interface key.
+ *
+ * bsp_ptr : pointer of the struct bfd_session_params (per-session id)
+ * vrf_id : VRF id recorded on the session params
+ * family : AF_INET (2) or AF_INET6 (10); expected AF_INET6 for this event
+ * dst/src : 16-byte in6_addr link-local pair (only first 4 bytes for AF_INET)
+ */
+TRACEPOINT_EVENT(
+ frr_libfrr,
+ bfd_sess_defer_linklocal_without_intf,
+ TP_ARGS(
+ void *, bsp,
+ uint32_t, vrf_id,
+ uint8_t, family,
+ const void *, dst,
+ const void *, src
+ ),
+ TP_FIELDS(
+ ctf_integer_hex(intptr_t, bsp_ptr, (intptr_t)bsp)
+ ctf_integer(uint32_t, vrf_id, vrf_id)
+ ctf_integer(uint8_t, family, family)
+ ctf_array(uint8_t, dst, dst ? (const uint8_t *)dst : (const uint8_t[16]) {0}, 16)
+ ctf_array(uint8_t, src, src ? (const uint8_t *)src : (const uint8_t[16]) {0}, 16)
+ )
+)
+TRACEPOINT_LOGLEVEL(frr_libfrr, bfd_sess_defer_linklocal_without_intf, TRACE_INFO)
+
TRACEPOINT_EVENT(
frr_libfrr,
hash_get,
diff --git a/tools/frr_babeltrace.py b/tools/frr_babeltrace.py
index 8f15032dff..29831b60b5 100755
--- a/tools/frr_babeltrace.py
+++ b/tools/frr_babeltrace.py
@@ -782,6 +782,19 @@ def parse_frr_bfd_stats_error(event):
parse_event(event, field_parsers)
+def parse_frr_libfrr_bfd_sess_defer_linklocal_without_intf(event):
+ """Parse BFD client-lib single-hop link-local defer events (lib/bfd.c)."""
+ family = event.get("family", 0)
+ field_parsers = {
+ "family": lambda x: "IPv4" if x == socket.AF_INET
+ else "IPv6" if x == socket.AF_INET6
+ else f"AF_{x}",
+ "dst": lambda x: print_bfd_addr(x, family) if family else "N/A",
+ "src": lambda x: print_bfd_addr(x, family) if family else "N/A",
+ }
+ parse_event(event, field_parsers)
+
+
############################ BFD parsers - end #################################
@@ -2000,6 +2013,8 @@ def main():
"frr_bfd:ptm_config_refcount_error": parse_frr_bfd_ptm_config_refcount_error,
"frr_bfd:packet_send_error": parse_frr_bfd_packet_send_error,
"frr_bfd:stats_error": parse_frr_bfd_stats_error,
+ "frr_libfrr:bfd_sess_defer_linklocal_without_intf":
+ parse_frr_libfrr_bfd_sess_defer_linklocal_without_intf,
}
# get the trace path from the first command line argument