Skip to content

Commit ae2a494

Browse files
committed
initial sbfd api
Signed-off-by: Jason Bos <jbos@cisco.com>
1 parent 2c74f46 commit ae2a494

File tree

2 files changed

+349
-0
lines changed

2 files changed

+349
-0
lines changed

doc/BFD/Seamless-BFD.md

Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
# Seamless BFD (S-BFD)
2+
3+
Title | Seamless BFD (S-BFD)
4+
------------|----------------
5+
Authors | Jason Bos
6+
Status | In review
7+
Type | Standards track
8+
Created | 10/10/2025
9+
SAI-Version | 1.16
10+
11+
Seamless Bidirectional Forwarding Detection (S-BFD) provides a simplified mechanism for continuity testing and validation of forwarding paths. Unlike traditional BFD, S-BFD does not require session establishment or negotiation - instead, it uses a reflector model where one side (the initiator) can immediately begin sending BFD packets to the other side (the reflector) without coordinated session state.
12+
13+
S-BFD is useful for:
14+
- Rapid path validation without session overhead
15+
- Monitoring with minimal state on reflectors
16+
- Validation of return paths in asymmetric routing scenarios
17+
- Scaling to large numbers of monitored paths
18+
19+
SAI supports S-BFD through two session types:
20+
21+
```
22+
typedef enum _sai_bfd_session_type_t
23+
{
24+
...
25+
/** S-BFD Reflector */
26+
SAI_BFD_SESSION_TYPE_REFLECTOR,
27+
28+
/** S-BFD Initiator */
29+
SAI_BFD_SESSION_TYPE_INITIATOR,
30+
...
31+
} sai_bfd_session_type_t;
32+
```
33+
34+
### S-BFD Reflector
35+
36+
The S-BFD reflector operates in a stateless manner. When configured, the reflector:
37+
- Listens for incoming S-BFD control packets
38+
- Reflects packets back to the initiator
39+
- Does not maintain per-session state
40+
- Uses the local discriminator to identify the reflector endpoint
41+
42+
Key attributes for a reflector session:
43+
- `SAI_BFD_SESSION_ATTR_TYPE`: Set to `SAI_BFD_SESSION_TYPE_REFLECTOR`
44+
- `SAI_BFD_SESSION_ATTR_LOCAL_DISCRIMINATOR`: Identifies the reflector (must be well-known)
45+
- `SAI_BFD_SESSION_ATTR_SRC_IP_ADDRESS`: Source IP for reflected packets
46+
47+
### S-BFD Initiator
48+
49+
The S-BFD initiator actively monitors paths by sending S-BFD control packets. The initiator:
50+
- Sends S-BFD packets with the reflector's discriminator as the destination
51+
- Monitors returned packets to verify path continuity
52+
- Maintains session state and detects failures based on timeout
53+
- Can dynamically adjust monitoring parameters
54+
55+
## Usage Example: S-BFD Reflector
56+
57+
The following example demonstrates how to configure an S-BFD reflector on a network device. The reflector uses a well-known discriminator (4) that initiators will use to send S-BFD packets.
58+
59+
```c
60+
/*****************************************************
61+
* Create an S-BFD Reflector Session
62+
*
63+
* This reflector will:
64+
* - Listen on discriminator 4
65+
* - Reflect S-BFD packets back to any initiator
66+
* - Operate statelessly
67+
*****************************************************/
68+
69+
sai_object_id_t sbfd_reflector_session;
70+
std::vector<sai_attribute_t> attrs;
71+
sai_attribute_t attr;
72+
73+
// Set session type to reflector
74+
attr.id = SAI_BFD_SESSION_ATTR_TYPE;
75+
attr.value.s32 = SAI_BFD_SESSION_TYPE_REFLECTOR;
76+
attrs.push_back(attr);
77+
78+
// Set local discriminator (well-known value for this reflector)
79+
attr.id = SAI_BFD_SESSION_ATTR_LOCAL_DISCRIMINATOR;
80+
attr.value.u32 = 4;
81+
attrs.push_back(attr);
82+
83+
// Set hardware lookup valid to true for packet processing
84+
attr.id = SAI_BFD_SESSION_ATTR_HW_LOOKUP_VALID;
85+
attr.value.booldata = true;
86+
attrs.push_back(attr);
87+
88+
// Set virtual router for routing lookup
89+
attr.id = SAI_BFD_SESSION_ATTR_VIRTUAL_ROUTER;
90+
attr.value.oid = vrf_id; // Virtual router object
91+
attrs.push_back(attr);
92+
93+
// Set source IP address (reflector's IP)
94+
attr.id = SAI_BFD_SESSION_ATTR_SRC_IP_ADDRESS;
95+
attr.value.ipaddr.addr_family = SAI_IP_ADDR_FAMILY_IPV4;
96+
inet_pton(AF_INET, "192.0.2.1", &attr.value.ipaddr.addr.ip4);
97+
attrs.push_back(attr);
98+
99+
// Set IP header version
100+
attr.id = SAI_BFD_SESSION_ATTR_IPHDR_VERSION;
101+
attr.value.u8 = 4;
102+
attrs.push_back(attr);
103+
104+
// Set encapsulation type (no encapsulation for basic S-BFD)
105+
attr.id = SAI_BFD_SESSION_ATTR_BFD_ENCAPSULATION_TYPE;
106+
attr.value.s32 = SAI_BFD_ENCAPSULATION_TYPE_NONE;
107+
attrs.push_back(attr);
108+
109+
// Optional: Set TTL for reflected packets
110+
attr.id = SAI_BFD_SESSION_ATTR_TTL;
111+
attr.value.u8 = 255;
112+
attrs.push_back(attr);
113+
114+
// Optional: Set TOS/DSCP for reflected packets
115+
attr.id = SAI_BFD_SESSION_ATTR_TOS;
116+
attr.value.u8 = 0xC0; // CS6 for network control
117+
attrs.push_back(attr);
118+
119+
// Create the reflector session
120+
sai_bfd_api->create_bfd_session(
121+
&sbfd_reflector_session,
122+
g_switch_id,
123+
attrs.size(),
124+
attrs.data());
125+
126+
```
127+
128+
## Usage Example: S-BFD Initiator
129+
130+
The following example demonstrates how to configure an S-BFD initiator that monitors path connectivity to the reflector configured in the previous example.
131+
132+
```c
133+
/*****************************************************
134+
* Create an S-BFD Initiator Session
135+
*
136+
* This initiator will:
137+
* - Send S-BFD packets to reflector at 192.0.2.1
138+
* - Use remote discriminator 4 (reflector's discriminator)
139+
* - Monitor path with 50ms intervals
140+
* - Detect failure after 3 missed packets (150ms)
141+
*****************************************************/
142+
143+
sai_object_id_t sbfd_initiator_session;
144+
std::vector<sai_attribute_t> attrs;
145+
sai_attribute_t attr;
146+
147+
// Set session type to initiator
148+
attr.id = SAI_BFD_SESSION_ATTR_TYPE;
149+
attr.value.s32 = SAI_BFD_SESSION_TYPE_INITIATOR;
150+
attrs.push_back(attr);
151+
152+
// Set local discriminator (unique on this initiator)
153+
attr.id = SAI_BFD_SESSION_ATTR_LOCAL_DISCRIMINATOR;
154+
attr.value.u32 = 99;
155+
attrs.push_back(attr);
156+
157+
// Set remote discriminator (reflector's well-known discriminator)
158+
attr.id = SAI_BFD_SESSION_ATTR_REMOTE_DISCRIMINATOR;
159+
attr.value.u32 = 4;
160+
attrs.push_back(attr);
161+
162+
// Set hardware lookup valid to true
163+
attr.id = SAI_BFD_SESSION_ATTR_HW_LOOKUP_VALID;
164+
attr.value.booldata = true;
165+
attrs.push_back(attr);
166+
167+
// Set virtual router for routing lookup
168+
attr.id = SAI_BFD_SESSION_ATTR_VIRTUAL_ROUTER;
169+
attr.value.oid = vrf_id; // Virtual router object
170+
attrs.push_back(attr);
171+
172+
// Set source IP address (initiator's IP)
173+
attr.id = SAI_BFD_SESSION_ATTR_SRC_IP_ADDRESS;
174+
attr.value.ipaddr.addr_family = SAI_IP_ADDR_FAMILY_IPV4;
175+
inet_pton(AF_INET, "198.51.100.1", &attr.value.ipaddr.addr.ip4);
176+
attrs.push_back(attr);
177+
178+
// Set destination IP address (reflector's IP)
179+
attr.id = SAI_BFD_SESSION_ATTR_DST_IP_ADDRESS;
180+
attr.value.ipaddr.addr_family = SAI_IP_ADDR_FAMILY_IPV4;
181+
inet_pton(AF_INET, "192.0.2.1", &attr.value.ipaddr.addr.ip4);
182+
attrs.push_back(attr);
183+
184+
// Set UDP source port (dynamic port for this session)
185+
attr.id = SAI_BFD_SESSION_ATTR_UDP_SRC_PORT;
186+
attr.value.u32 = 49152;
187+
attrs.push_back(attr);
188+
189+
// Set minimum transmit interval (50000 microseconds = 50 ms)
190+
attr.id = SAI_BFD_SESSION_ATTR_MIN_TX;
191+
attr.value.u32 = 50000;
192+
attrs.push_back(attr);
193+
194+
// Set minimum receive interval (50000 microseconds = 50 ms)
195+
attr.id = SAI_BFD_SESSION_ATTR_MIN_RX;
196+
attr.value.u32 = 50000;
197+
attrs.push_back(attr);
198+
199+
// Set detection multiplier (3 missed packets = failure)
200+
attr.id = SAI_BFD_SESSION_ATTR_MULTIPLIER;
201+
attr.value.u8 = 3;
202+
attrs.push_back(attr);
203+
204+
// Set IP header version
205+
attr.id = SAI_BFD_SESSION_ATTR_IPHDR_VERSION;
206+
attr.value.u8 = 4;
207+
attrs.push_back(attr);
208+
209+
// Set encapsulation type
210+
attr.id = SAI_BFD_SESSION_ATTR_BFD_ENCAPSULATION_TYPE;
211+
attr.value.s32 = SAI_BFD_ENCAPSULATION_TYPE_NONE;
212+
attrs.push_back(attr);
213+
214+
// Optional: Set TTL
215+
attr.id = SAI_BFD_SESSION_ATTR_TTL;
216+
attr.value.u8 = 255;
217+
attrs.push_back(attr);
218+
219+
// Optional: Set TOS/DSCP
220+
attr.id = SAI_BFD_SESSION_ATTR_TOS;
221+
attr.value.u8 = 0xC0; // CS6 for network control
222+
attrs.push_back(attr);
223+
224+
// Optional: Enable multi-hop for non-adjacent reflector
225+
attr.id = SAI_BFD_SESSION_ATTR_MULTIHOP;
226+
attr.value.booldata = true;
227+
attrs.push_back(attr);
228+
229+
// Create the initiator session
230+
sai_bfd_api->create_bfd_session(
231+
&sbfd_initiator_session,
232+
g_switch_id,
233+
attrs.size(),
234+
attrs.data());
235+
```
236+
237+
## Usage Example: S-BFD Initiator with SRv6 Encapsulation
238+
239+
The following example demonstrates how to configure an S-BFD initiator with SRv6 encapsulation for monitoring paths in an SRv6 network.
240+
241+
```c
242+
/*****************************************************
243+
* Create an S-BFD Initiator Session with SRv6 Encapsulation
244+
*
245+
* This initiator will:
246+
* - Send S-BFD packets encapsulated in SRv6
247+
* - Use SRv6 segment list for path steering
248+
* - Monitor path with 50ms intervals
249+
* - Detect failure after 3 missed packets (150ms)
250+
*****************************************************/
251+
252+
sai_object_id_t sbfd_srv6_initiator_session;
253+
std::vector<sai_attribute_t> attrs;
254+
sai_attribute_t attr;
255+
256+
// Set session type to initiator
257+
attr.id = SAI_BFD_SESSION_ATTR_TYPE;
258+
attr.value.s32 = SAI_BFD_SESSION_TYPE_INITIATOR;
259+
attrs.push_back(attr);
260+
261+
// Set local discriminator (unique on this initiator)
262+
attr.id = SAI_BFD_SESSION_ATTR_LOCAL_DISCRIMINATOR;
263+
attr.value.u32 = 99;
264+
attrs.push_back(attr);
265+
266+
// Set remote discriminator (reflector's well-known discriminator)
267+
attr.id = SAI_BFD_SESSION_ATTR_REMOTE_DISCRIMINATOR;
268+
attr.value.u32 = 4;
269+
attrs.push_back(attr);
270+
271+
// Set hardware lookup valid to true
272+
attr.id = SAI_BFD_SESSION_ATTR_HW_LOOKUP_VALID;
273+
attr.value.booldata = true;
274+
attrs.push_back(attr);
275+
276+
// Set virtual router for routing lookup
277+
attr.id = SAI_BFD_SESSION_ATTR_VIRTUAL_ROUTER;
278+
attr.value.oid = vrf_id; // Virtual router object
279+
attrs.push_back(attr);
280+
281+
// Set source IP address for inner BFD packet (initiator's IP)
282+
attr.id = SAI_BFD_SESSION_ATTR_SRC_IP_ADDRESS;
283+
attr.value.ipaddr.addr_family = SAI_IP_ADDR_FAMILY_IPV6;
284+
inet_pton(AF_INET6, "2001:db8:1::1", &attr.value.ipaddr.addr.ip6);
285+
attrs.push_back(attr);
286+
287+
// Set destination IP address for inner BFD packet (reflector's IP)
288+
attr.id = SAI_BFD_SESSION_ATTR_DST_IP_ADDRESS;
289+
attr.value.ipaddr.addr_family = SAI_IP_ADDR_FAMILY_IPV6;
290+
inet_pton(AF_INET6, "2001:db8:2::1", &attr.value.ipaddr.addr.ip6);
291+
attrs.push_back(attr);
292+
293+
// Set UDP source port (dynamic port for this session)
294+
attr.id = SAI_BFD_SESSION_ATTR_UDP_SRC_PORT;
295+
attr.value.u32 = 49153;
296+
attrs.push_back(attr);
297+
298+
// Set minimum transmit interval (50000 microseconds = 50 ms)
299+
attr.id = SAI_BFD_SESSION_ATTR_MIN_TX;
300+
attr.value.u32 = 50000;
301+
attrs.push_back(attr);
302+
303+
// Set minimum receive interval (50000 microseconds = 50 ms)
304+
attr.id = SAI_BFD_SESSION_ATTR_MIN_RX;
305+
attr.value.u32 = 50000;
306+
attrs.push_back(attr);
307+
308+
// Set detection multiplier (3 missed packets = failure)
309+
attr.id = SAI_BFD_SESSION_ATTR_MULTIPLIER;
310+
attr.value.u8 = 3;
311+
attrs.push_back(attr);
312+
313+
// Set IP header version for inner packet
314+
attr.id = SAI_BFD_SESSION_ATTR_IPHDR_VERSION;
315+
attr.value.u8 = 6;
316+
attrs.push_back(attr);
317+
318+
// Set encapsulation type to SRv6
319+
attr.id = SAI_BFD_SESSION_ATTR_BFD_ENCAPSULATION_TYPE;
320+
attr.value.s32 = SAI_BFD_ENCAPSULATION_TYPE_SRV6;
321+
attrs.push_back(attr);
322+
323+
// Set tunnel source IP (outer IPv6 header source)
324+
attr.id = SAI_BFD_SESSION_ATTR_TUNNEL_SRC_IP_ADDRESS;
325+
attr.value.ipaddr.addr_family = SAI_IP_ADDR_FAMILY_IPV6;
326+
inet_pton(AF_INET6, "2001:db8:100::1", &attr.value.ipaddr.addr.ip6);
327+
attrs.push_back(attr);
328+
329+
// Set SRv6 SID list for segment routing
330+
// Assumes srv6_sidlist_id was created previously with desired segment list
331+
attr.id = SAI_BFD_SESSION_ATTR_SRV6_SIDLIST_ID;
332+
attr.value.oid = srv6_sidlist_id; // SRv6 SID list object
333+
attrs.push_back(attr);
334+
335+
// Create the SRv6-encapsulated initiator session
336+
sai_bfd_api->create_bfd_session(
337+
&sbfd_srv6_initiator_session,
338+
g_switch_id,
339+
attrs.size(),
340+
attrs.data());

inc/saibfd.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ typedef enum _sai_bfd_session_type_t
5050
/** Asynchronous Passive Mode */
5151
SAI_BFD_SESSION_TYPE_ASYNC_PASSIVE,
5252

53+
/** S-BFD Reflector */
54+
SAI_BFD_SESSION_TYPE_REFLECTOR,
55+
56+
/** S-BFD Initiator */
57+
SAI_BFD_SESSION_TYPE_INITIATOR,
58+
5359
} sai_bfd_session_type_t;
5460

5561
/**
@@ -191,6 +197,7 @@ typedef enum _sai_bfd_session_attr_t
191197
*
192198
* @type sai_uint32_t
193199
* @flags MANDATORY_ON_CREATE | CREATE_ONLY
200+
* @condition SAI_BFD_SESSION_ATTR_TYPE == SAI_BFD_SESSION_TYPE_DEMAND_ACTIVE or SAI_BFD_SESSION_ATTR_TYPE == SAI_BFD_SESSION_TYPE_DEMAND_PASSIVE or SAI_BFD_SESSION_ATTR_TYPE == SAI_BFD_SESSION_TYPE_ASYNC_ACTIVE or SAI_BFD_SESSION_ATTR_TYPE == SAI_BFD_SESSION_TYPE_ASYNC_PASSIVE or SAI_BFD_SESSION_ATTR_TYPE == SAI_BFD_SESSION_TYPE_INITIATOR
194201
*/
195202
SAI_BFD_SESSION_ATTR_REMOTE_DISCRIMINATOR,
196203

@@ -199,6 +206,7 @@ typedef enum _sai_bfd_session_attr_t
199206
*
200207
* @type sai_uint32_t
201208
* @flags MANDATORY_ON_CREATE | CREATE_ONLY
209+
* @condition SAI_BFD_SESSION_ATTR_TYPE == SAI_BFD_SESSION_TYPE_DEMAND_ACTIVE or SAI_BFD_SESSION_ATTR_TYPE == SAI_BFD_SESSION_TYPE_DEMAND_PASSIVE or SAI_BFD_SESSION_ATTR_TYPE == SAI_BFD_SESSION_TYPE_ASYNC_ACTIVE or SAI_BFD_SESSION_ATTR_TYPE == SAI_BFD_SESSION_TYPE_ASYNC_PASSIVE or SAI_BFD_SESSION_ATTR_TYPE == SAI_BFD_SESSION_TYPE_INITIATOR
202210
*/
203211
SAI_BFD_SESSION_ATTR_UDP_SRC_PORT,
204212

@@ -308,6 +316,7 @@ typedef enum _sai_bfd_session_attr_t
308316
*
309317
* @type sai_ip_address_t
310318
* @flags MANDATORY_ON_CREATE | CREATE_ONLY
319+
* @condition SAI_BFD_SESSION_ATTR_TYPE == SAI_BFD_SESSION_TYPE_DEMAND_ACTIVE or SAI_BFD_SESSION_ATTR_TYPE == SAI_BFD_SESSION_TYPE_DEMAND_PASSIVE or SAI_BFD_SESSION_ATTR_TYPE == SAI_BFD_SESSION_TYPE_ASYNC_ACTIVE or SAI_BFD_SESSION_ATTR_TYPE == SAI_BFD_SESSION_TYPE_ASYNC_PASSIVE or SAI_BFD_SESSION_ATTR_TYPE == SAI_BFD_SESSION_TYPE_INITIATOR
311320
*/
312321
SAI_BFD_SESSION_ATTR_DST_IP_ADDRESS,
313322

0 commit comments

Comments
 (0)