1 # BFD module {#bfd_doc}
5 Bidirectional Forwarding Detection in VPP currently supports single-hop UDP
6 transport based on RFC 5880 and RFC 5881.
12 BFD sessions are created using APIs only. The following CLIs are implemented,
13 which call the APIs to manipulate the BFD:
17 > show bfd [keys|sessions|echo-source]
19 Show the existing keys, sessions or echo-source.
23 ##### Create a new key or modify an existing key
25 > bfd key set conf-key-id <id> type <keyed-sha1|meticulous-keyed-sha1> secret <secret>
29 * conf-key-id - local configuration key ID, used to uniquely identify this key
30 * type - type of the key
31 * secret - shared secret (hex data)
35 > bfd key set conf-key-id 2368880803 type meticulous-keyed-sha1 secret 69d685b0d990cdba46872706dc
39 * in-use key cannot be modified
41 ##### Delete an existing key
43 > bfd key del conf-key-id <id>
47 * conf-key-id - local configuration key ID, used to uniquely identify this key
51 > bfd key del conf-key-id 2368880803
55 * in-use key cannot be deleted
57 ##### Create a new (plain or authenticated) BFD session
59 > bfd udp session add interface <interface> local-addr <address> peer-addr <address> desired-min-tx <interval> required-min-rx <interval> detect-mult <multiplier> [ conf-key-id <ID> bfd-key-id <ID> ]
63 * interface - interface to which this session is tied to
64 * local-addr - local address (ipv4 or ipv6)
65 * peer-addr - peer address (ipv4 or ipv6, must match local-addr family)
66 * desired-min-tx - desired minimum tx interval (microseconds)
67 * required-min-rx - required minimum rx interval (microseconds)
68 * detect-mult - detect multiplier (must be non-zero)
69 * conf-key-id - local configuration key ID
70 * bfd-key-id - BFD key ID, as carried in BFD control frames
74 > bfd udp session add interface pg0 local-addr fd01:1::1 peer-addr fd01:1::2 desired-min-tx 100000 required-min-rx 100000 detect-mult 3 conf-key-id 1029559112 bfd-key-id 13
78 * if conf-key-id and bfd-key-id are not specified, session is non-authenticated
79 * desired-min-tx controls desired transmission rate of both control frames and echo packets
81 ##### Modify BFD session
83 > bfd udp session mod interface <interface> local-addr <address> peer-addr <address> desired-min-tx <interval> required-min-rx <interval> detect-mult <multiplier>
87 * interface - interface to which this session is tied to
88 * local-addr - local address (ipv4 or ipv6)
89 * peer-addr - peer address (ipv4 or ipv6, must match local-addr family)
90 * desired-min-tx - desired minimum tx interval (microseconds)
91 * required-min-rx - required minimum rx interval (microseconds)
92 * detect-mult - detect multiplier (must be non-zero)
96 > bfd udp session mod interface pg0 local-addr 172.16.1.1 peer-addr 172.16.1.2 desired-min-tx 300000 required-min-rx 200000 detect-mult 12
100 * desired-min-tx controls desired transmission rate of both control frames and echo packets
102 ##### Delete an existing BFD session
104 > bfd udp session del interface <interface> local-addr <address> peer-addr<address>
108 * interface - interface to which this session is tied to
109 * local-addr - local address (ipv4 or ipv6)
110 * peer-addr - peer address (ipv4 or ipv6, must match local-addr family)
114 > bfd udp session del interface pg0 local-addr 172.16.1.1 peer-addr 172.16.1.2
116 ##### Set session admin-up or admin-down
118 > bfd udp session set-flags interface <interface> local-addr <address> peer-addr <address> admin <up|down>
122 * interface - interface to which this session is tied to
123 * local-addr - local address (ipv4 or ipv6)
124 * peer-addr - peer address (ipv4 or ipv6, must match local-addr family)
125 * admin - up/down based on desired action
129 > bfd udp session set-flags admin down interface pg0 local-addr 172.16.1.1 peer-addr 172.16.1.2
131 ##### Activate/change authentication for existing session
133 > bfd udp session auth activate interface <interface> local-addr <address> peer-addr <address> conf-key-id <ID> bfd-key-id <ID> [ delayed <yes|no> ]
137 * interface - interface to which this session is tied to
138 * local-addr - local address (ipv4 or ipv6)
139 * peer-addr - peer address (ipv4 or ipv6, must match local-addr family)
140 * conf-key-id - local configuration key ID
141 * bfd-key-id - BFD key ID, as carried in BFD control frames
142 * delayed - is yes then this action is delayed until the peer performs the same action
146 > bfd udp session auth activate interface pg0 local-addr 172.16.1.1 peer-addr 172.16.1.2 conf-key-id 540928695 bfd-key-id 239 delayed yes
150 * see [Delayed option] for more information
152 ##### Deactivate authentication for existing session
154 > bfd udp session auth deactivate interface <interface> local-addr <address> peer-addr <address> [ delayed <yes|no> ]
158 * interface - interface to which this session is tied to
159 * local-addr - local address (ipv4 or ipv6)
160 * peer-addr - peer address (ipv4 or ipv6, must match local-addr family)
161 * delayed - is yes then this action is delayed until the peer performs the same action
165 > bfd udp session auth deactivate interface pg0 local-addr 172.16.1.1 peer-addr 172.16.1.2
169 * see [Delayed option] for more information
171 ##### Set echo-source interface
173 > bfd udp echo-source set interface <interface>
177 * interface - interface used for getting source address for echo packets
181 > bfd udp echo-source set interface loop0
183 ##### Delete echo-source interface
185 > bfd udp echo-source del
189 > bfd udp echo-source del
193 BFD sessions should be authenticated for security purposes. SHA1 and meticulous
194 SHA1 authentication is supported by VPP. First, authentication keys are
195 configured in VPP and afterwards they can be used by sessions.
197 There are two key IDs in the scope of BFD session:
199 * configuration key ID is the internal unique key ID inside VPP and is never
200 communicated to any peer, it serves only the purpose of identifying the key
201 * BFD key ID is the key ID carried in BFD control frames and is used for
202 verifying authentication
204 #### Turning auth on/off
206 Authentication can be turned on or off at any time. Care must be taken however,
207 to either synchronize the authentication manipulation with peer's actions
208 to avoid the session going down.
212 Delayed option is useful for synchronizing authentication changes with a peer.
213 If it's specified, then authentication change is not performed immediately.
214 In this case, VPP continues to transmit packets using the old authentication
215 method (unauthenticated or using old sha1 key). If a packet is received, which
216 does not pass the current authentication, then VPP tries to authenticate it
217 using the new method (which might be none, if deactivating authentication)
218 and if it passes, then the new authentication method is put in use.
220 The recommended procedure for enabling/changing/disabling session
223 1. perform authentication change on vpp's side with delayed option set to yes
224 2. perform authentication change on peer's side (without delayed option)
228 * if both peers use delayed option at the same time, the change will never
229 be carried out, since none of the peers will see any packet with the new
230 authentication which could trigger the change
231 * remote peer does not need to support or even be aware of this mechanism
232 for it to work properly
237 Echo function is used by VPP whenever a peer declares the willingness
238 to support it, echo-source is set and it contains a usable subnet (see below).
239 When echo function is switched on, the required min rx interval advertised
240 to peer is set to 1 second (or the configured value, if its higher).
242 #### Echo source address
244 Because echo packets are only looped back (and not processed in any way)
245 by a peer, it's necessary to set the source address in a way which avoids
246 packet drop due to spoofing protection by VPP. Per RFC, the source address
247 should not be in the subnet set on the interface over which the echo packets
248 are sent. Also, it must not be any VPP-local address, otherwise the packet
249 gets dropped on receipt by VPP. The solution is to create a loopback interface
250 with a (private) IPv4/IPv6 subnet assigned as echo-source. The BFD then picks
251 an unused address from the subnet by flipping the last bit and uses that as
252 source address in the echo packets, thus meeting RFC recommendation while
253 avoiding spoofing protection.
255 Example: if 10.10.10.3/31 is the subnet, then 10.10.10.2 will be used as
256 source address in (IPv4) echo packets
260 Demand mode is respected by VPP, but not used locally. The only scenario when
261 demand mode could make sense currently is when echo is active. Because echo
262 packets are inherently insecure against an adversary looping them back a poll
263 sequence would be required for slow periodic connectivity verification anyway.
264 It's more efficient to just ask the remote peer to send slow periodic control
265 frames without VPP initiating periodic poll sequences.
269 Session may be put admin-down at any time. This immediately causes the state
270 to be changed to AdminDown and remain so unless the session is put admin-up.
272 ## BFD implementation notes
274 Because BFD can work over different transport layers, the BFD code is separated
275 into core BFD functionality - main module implemented in bfd_main.c
276 and transport-specific code implemented in bfd_udp.c.
280 Main module is responsible for handling all the BFD functionality defined
285 Internal APIs defined in bfd_main.h are called from transport-specific code
286 to create/modify/delete
290 When a packet is received by the transport layer, it is forwarded to main
291 module (to main thread) via an RPC call. At this point, the authentication has
292 been verified, so the packet is consumed, session parameters are updated
293 accordingly and state change (if applicable). Based on these, the timeouts
294 are adjusted if required and an event is sent to the process node to wake up
295 and recalculate sleep time.
299 Main module allocates a vlib_buffer_t, creates the required BFD frame (control
300 or echo in it), then calls the transport layer to add the transport layer.
301 Then a frame containing the buffer to the aprropriate node is created
306 Main module implements one process node which is a simple loop. The process
307 node gets next timeout from the timer wheel, sleeps until the timeout expires
308 and then calls a timeout routine which drives the state machine for each
309 session which timed out. The sleep is interrupted externally via vlib event,
310 when a session is added or modified in a way which might require timer wheel
311 manipulation. In this case the caller inserts the necessary timeout to timer
312 wheel and then signals the process node to wake up early, handle possible
313 timeouts and recalculate the sleep time again.
317 Default state of BFD session when created is Down, per RFC 5880. State changes
318 to Init, Up or Down based on events like received state from peer and timeouts.
319 The session state can be set AdminDown using a binary API, which prevents it
320 from going to any other state, until this limitation is removed. This state
321 is advertised to peers in slow periodic control frames.
323 For each session, the following timeouts are maintained:
325 1. tx timeout - used for sending out control frames
326 2. rx timeout - used for detecting session timeout
327 3. echo tx timeout - used for sending out echo frames
328 3. echo rx timeout - used for detecting session timeout based on echo
330 These timeouts are maintained in cpu clocks and recalculated when appropriate
331 (e.g. rx timeout is bumped when a packet is received, keeping the session
332 alive). Only the earliest timeout is inserted into the timer wheel at a time
333 and timer wheel events are never deleted, rather spurious events are ignored.
334 This allows efficient operation, like not inserting events into timing wheel
335 for each packet received or ignoring left-over events in case a bfd session
336 gets removed and a new one is recreated with the same session index.
338 #### Authentication keys management
340 Authentication keys are managed internally in a pool, with each key tracking
341 it's use count. The removal/modification is only allowed if the key is not in
346 UDP module is responsible for:
348 1. public APIs/CLIs to configure BFD over UDP.
349 2. support code called by main module to encapsulate/decapsulate BFD packets
351 This module implements two graph nodes - for consuming ipv4 and ipv6 packets
352 target at BFD ports 3874 and 3875.
356 BFD packet receipt receipt starts in the bfd udp graph nodes. Since the code
357 needs to verify IP/UDP header data, it relies on ip4-local (and ip6-local)
358 nodes to store pointers to the appropriate headers. First, your discriminator
359 is extracted from BFD packet and used to lookup the existing session. In case
360 it's zero, the pair of IP addresses and sw_if_index is used to lookup session.
361 Then, main module is called to verify the authentication, if present.
362 Afterwards a check is made if the IP/UDP headers are correct. If yes, then
363 an RPC call is made to the main thread to consume the packet and take action
366 #### Packet transmission
368 When process node decides that there is a need to transmit the packet, it
369 creates a buffer, fills the BFD frame data in and calls the UDP module to
370 add the transport layer. This is a simple operation for the control frames
371 consisting of just adding UDP/IP headers based on session data. For echo
372 frames, an additional step, looking at the echo-source interface and picking
373 and address is performed and if this fails, then the packet cannot be
374 transmitted and an error is returned to main thread.