BFD: documentation

Change-Id: I06a23d24340c5527f3848177d2178bf3e55f7614
Signed-off-by: Klement Sekera <ksekera@cisco.com>
diff --git a/src/vnet/bfd/bfd_api.c b/src/vnet/bfd/bfd_api.c
index e64df48..185c03c 100644
--- a/src/vnet/bfd/bfd_api.c
+++ b/src/vnet/bfd/bfd_api.c
@@ -16,6 +16,10 @@
  * limitations under the License.
  *------------------------------------------------------------------
  */
+/**
+ * @file
+ * @brief BFD binary API implementation
+ */
 
 #include <vnet/vnet.h>
 #include <vlibmemory/api.h>
diff --git a/src/vnet/bfd/bfd_api.h b/src/vnet/bfd/bfd_api.h
index 35ad3cd..9f0509d 100644
--- a/src/vnet/bfd/bfd_api.h
+++ b/src/vnet/bfd/bfd_api.h
@@ -14,7 +14,7 @@
  */
 /**
  * @file
- * @brief BFD global declarations
+ * @brief BFD API declarations
  */
 #ifndef __included_bfd_api_h__
 #define __included_bfd_api_h__
@@ -34,6 +34,9 @@
 #undef F
 } bfd_transport_e;
 
+/**
+ * @brief create a new bfd session
+ */
 vnet_api_error_t
 bfd_udp_add_session (u32 sw_if_index, const ip46_address_t * local_addr,
 		     const ip46_address_t * peer_addr,
@@ -41,39 +44,66 @@
 		     u8 detect_mult, u8 is_authenticated, u32 conf_key_id,
 		     u8 bfd_key_id);
 
+/**
+ * @brief modify existing session
+ */
 vnet_api_error_t
 bfd_udp_mod_session (u32 sw_if_index, const ip46_address_t * local_addr,
 		     const ip46_address_t * peer_addr,
 		     u32 desired_min_tx_usec, u32 required_min_rx_usec,
 		     u8 detect_mult);
 
+/**
+ * @brief delete existing session
+ */
 vnet_api_error_t bfd_udp_del_session (u32 sw_if_index,
 				      const ip46_address_t * local_addr,
 				      const ip46_address_t * peer_addr);
 
+/**
+ * @brief set session admin down/up
+ */
 vnet_api_error_t bfd_udp_session_set_flags (u32 sw_if_index,
 					    const ip46_address_t * local_addr,
 					    const ip46_address_t * peer_addr,
 					    u8 admin_up_down);
 
+/**
+ * @brief create or modify bfd authentication key
+ */
 vnet_api_error_t bfd_auth_set_key (u32 conf_key_id, u8 auth_type, u8 key_len,
 				   const u8 * key);
 
+/**
+ * @brief delete existing authentication key
+ */
 vnet_api_error_t bfd_auth_del_key (u32 conf_key_id);
 
+/**
+ * @brief activate authentication for existing session
+ */
 vnet_api_error_t bfd_udp_auth_activate (u32 sw_if_index,
 					const ip46_address_t * local_addr,
 					const ip46_address_t * peer_addr,
 					u32 conf_key_id, u8 bfd_key_id,
 					u8 is_delayed);
 
+/**
+ * @brief deactivate authentication for existing session
+ */
 vnet_api_error_t bfd_udp_auth_deactivate (u32 sw_if_index,
 					  const ip46_address_t * local_addr,
 					  const ip46_address_t * peer_addr,
 					  u8 is_delayed);
 
+/**
+ * @brief set echo-source interface
+ */
 vnet_api_error_t bfd_udp_set_echo_source (u32 loopback_sw_if_index);
 
+/**
+ * @brief unset echo-source interface
+ */
 vnet_api_error_t bfd_udp_del_echo_source ();
 
 #endif /* __included_bfd_api_h__ */
diff --git a/src/vnet/bfd/bfd_cli.c b/src/vnet/bfd/bfd_cli.c
index a3736d9..f15acb4 100644
--- a/src/vnet/bfd/bfd_cli.c
+++ b/src/vnet/bfd/bfd_cli.c
@@ -737,7 +737,7 @@
                 " peer-addr <peer-address>"
                 " conf-key-id <config key ID>"
                 " bfd-key-id <BFD key ID>"
-                " [ delayed <yes|no>]",
+                " [ delayed <yes|no> ]",
   .function = bfd_cli_udp_session_auth_activate,
 };
 
@@ -815,7 +815,7 @@
                 " interface <interface>"
                 " local-addr <local-address>"
                 " peer-addr <peer-address>"
-                "[ delayed <yes|no>]",
+                "[ delayed <yes|no> ]",
   .function = bfd_cli_udp_session_auth_deactivate,
 };
 /* *INDENT-ON* */
diff --git a/src/vnet/bfd/bfd_doc.md b/src/vnet/bfd/bfd_doc.md
index 3e86b17..7d7606e 100644
--- a/src/vnet/bfd/bfd_doc.md
+++ b/src/vnet/bfd/bfd_doc.md
@@ -1,3 +1,374 @@
-# BFD Notes    {#bfd_doc}
+# BFD module    {#bfd_doc}
 
-@todo Someone needs to produce this or remove the stub file.
+## Overview
+
+Bidirectional Forwarding Detection in VPP currently supports single-hop UDP
+transport based on RFC 5880 and RFC 5881.
+
+## Usage
+
+### General usage
+
+BFD sessions are created using APIs only. The following CLIs are implemented,
+which call the APIs to manipulate the BFD:
+
+#### Show commands:
+
+> show bfd [keys|sessions|echo-source]
+
+Show the existing keys, sessions or echo-source.
+
+#### Key manipulation
+
+##### Create a new key or modify an existing key
+
+> bfd key set conf-key-id <id> type <keyed-sha1|meticulous-keyed-sha1> secret <secret>
+
+Parameters:
+
+* conf-key-id     - local configuration key ID, used to uniquely identify this key
+* type            - type of the key
+* secret          - shared secret (hex data)
+
+Example:
+
+> bfd key set conf-key-id 2368880803 type meticulous-keyed-sha1 secret 69d685b0d990cdba46872706dc
+
+Notes:
+
+* in-use key cannot be modified
+
+##### Delete an existing key
+
+> bfd key del conf-key-id <id>
+
+Parameters:
+
+* conf-key-id     - local configuration key ID, used to uniquely identify this key
+
+Example:
+
+> bfd key del conf-key-id 2368880803
+
+Notes:
+
+*  in-use key cannot be deleted
+
+##### Create a new (plain or authenticated) BFD session
+
+> 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> ]
+
+Parameters:
+
+* interface       - interface to which this session is tied to
+* local-addr      - local address (ipv4 or ipv6)
+* peer-addr       - peer address (ipv4 or ipv6, must match local-addr family)
+* desired-min-tx  - desired minimum tx interval (microseconds)
+* required-min-rx - required minimum rx interval (microseconds)
+* detect-mult     - detect multiplier (must be non-zero)
+* conf-key-id     - local configuration key ID
+* bfd-key-id      - BFD key ID, as carried in BFD control frames
+
+Example:
+
+> 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
+
+Notes:
+
+* if conf-key-id and bfd-key-id are not specified, session is non-authenticated
+* desired-min-tx controls desired transmission rate of both control frames and echo packets
+
+##### Modify BFD session
+
+> bfd udp session mod interface <interface> local-addr <address> peer-addr <address> desired-min-tx <interval> required-min-rx <interval> detect-mult <multiplier>
+
+Parameters:
+
+* interface       - interface to which this session is tied to
+* local-addr      - local address (ipv4 or ipv6)
+* peer-addr       - peer address (ipv4 or ipv6, must match local-addr family)
+* desired-min-tx  - desired minimum tx interval (microseconds)
+* required-min-rx - required minimum rx interval (microseconds)
+* detect-mult     - detect multiplier (must be non-zero)
+
+Example:
+
+> 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
+
+Notes:
+
+* desired-min-tx controls desired transmission rate of both control frames and echo packets
+
+##### Delete an existing BFD session
+
+> bfd udp session del interface <interface> local-addr <address> peer-addr<address>
+
+Parameters:
+
+* interface       - interface to which this session is tied to
+* local-addr      - local address (ipv4 or ipv6)
+* peer-addr       - peer address (ipv4 or ipv6, must match local-addr family)
+
+Example:
+
+> bfd udp session del interface pg0 local-addr 172.16.1.1 peer-addr 172.16.1.2
+
+##### Set session admin-up or admin-down
+
+> bfd udp session set-flags interface <interface> local-addr <address> peer-addr <address> admin <up|down>
+
+Parameters:
+
+* interface       - interface to which this session is tied to
+* local-addr      - local address (ipv4 or ipv6)
+* peer-addr       - peer address (ipv4 or ipv6, must match local-addr family)
+* admin           - up/down based on desired action
+
+Example:
+
+> bfd udp session set-flags admin down interface pg0 local-addr 172.16.1.1 peer-addr 172.16.1.2
+
+##### Activate/change authentication for existing session
+
+> bfd udp session auth activate interface <interface> local-addr <address> peer-addr <address> conf-key-id <ID> bfd-key-id <ID> [ delayed <yes|no> ]
+
+Parameters:
+
+* interface       - interface to which this session is tied to
+* local-addr      - local address (ipv4 or ipv6)
+* peer-addr       - peer address (ipv4 or ipv6, must match local-addr family)
+* conf-key-id     - local configuration key ID
+* bfd-key-id      - BFD key ID, as carried in BFD control frames
+* delayed         - is yes then this action is delayed until the peer performs the same action
+
+Example:
+
+> 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
+
+Notes:
+
+* see [Delayed option] for more information
+
+##### Deactivate authentication for existing session
+
+> bfd udp session auth deactivate interface <interface> local-addr <address> peer-addr <address> [ delayed <yes|no> ]
+
+Parameters:
+
+* interface       - interface to which this session is tied to
+* local-addr      - local address (ipv4 or ipv6)
+* peer-addr       - peer address (ipv4 or ipv6, must match local-addr family)
+* delayed         - is yes then this action is delayed until the peer performs the same action
+
+Example:
+
+> bfd udp session auth deactivate interface pg0 local-addr 172.16.1.1 peer-addr 172.16.1.2
+
+Notes:
+
+* see [Delayed option] for more information
+
+##### Set echo-source interface
+
+> bfd udp echo-source set interface <interface>
+
+Parameters:
+
+* interface       - interface used for getting source address for echo packets
+
+Example:
+
+> bfd udp echo-source set interface loop0
+
+##### Delete echo-source interface
+
+> bfd udp echo-source del
+
+Example:
+
+> bfd udp echo-source del
+
+### Authentication
+
+BFD sessions should be authenticated for security purposes. SHA1 and meticulous
+SHA1 authentication is supported by VPP. First, authentication keys are
+configured in VPP and afterwards they can be used by sessions.
+
+There are two key IDs in the scope of BFD session:
+
+* configuration key ID is the internal unique key ID inside VPP and is never
+  communicated to any peer, it serves only the purpose of identifying the key
+* BFD key ID is the key ID carried in BFD control frames and is used for
+  verifying authentication
+
+#### Turning auth on/off
+
+Authentication can be turned on or off at any time. Care must be taken however,
+to either synchronize the authentication manipulation with peer's actions
+to avoid the session going down.
+
+##### Delayed option
+
+Delayed option is useful for synchronizing authentication changes with a peer.
+If it's specified, then authentication change is not performed immediately.
+In this case, VPP continues to transmit packets using the old authentication
+method (unauthenticated or using old sha1 key). If a packet is received, which
+does not pass the current authentication, then VPP tries to authenticate it
+using the new method (which might be none, if deactivating authentication)
+and if it passes, then the new authentication method is put in use.
+
+The recommended procedure for enabling/changing/disabling session 
+authentication is:
+
+1. perform authentication change on vpp's side with delayed option set to yes
+2. perform authentication change on peer's side (without delayed option)
+
+Notes:
+
+* if both peers use delayed option at the same time, the change will never
+  be carried out, since none of the peers will see any packet with the new
+  authentication which could trigger the change
+* remote peer does not need to support or even be aware of this mechanism
+  for it to work properly
+
+
+### Echo function
+
+Echo function is used by VPP whenever a peer declares the willingness
+to support it, echo-source is set and it contains a usable subnet (see below).
+When echo function is switched on, the required min rx interval advertised
+to peer is set to 1 second (or the configured value, if its higher).
+
+#### Echo source address
+
+Because echo packets are only looped back (and not processed in any way)
+by a peer, it's necessary to set the source address in a way which avoids
+packet drop due to spoofing protection by VPP. Per RFC, the source address
+should not be in the subnet set on the interface over which the echo packets
+are sent. Also, it must not be any VPP-local address, otherwise the packet
+gets dropped on receipt by VPP. The solution is to create a loopback interface
+with a (private) IPv4/IPv6 subnet assigned as echo-source. The BFD then picks
+an unused address from the subnet by flipping the last bit and uses that as
+source address in the echo packets, thus meeting RFC recommendation while
+avoiding spoofing protection.
+
+Example: if 10.10.10.3/31 is the subnet, then 10.10.10.2 will be used as
+         source address in (IPv4) echo packets
+
+### Demand mode
+
+Demand mode is respected by VPP, but not used locally. The only scenario when
+demand mode could make sense currently is when echo is active. Because echo
+packets are inherently insecure against an adversary looping them back a poll
+sequence would be required for slow periodic connectivity verification anyway.
+It's more efficient to just ask the remote peer to send slow periodic control
+frames without VPP initiating periodic poll sequences.
+
+### Admin-down
+
+Session may be put admin-down at any time. This immediately causes the state
+to be changed to AdminDown and remain so unless the session is put admin-up.
+
+## BFD implementation notes
+
+Because BFD can work over different transport layers, the BFD code is separated
+into core BFD functionality - main module implemented in bfd_main.c
+and transport-specific code implemented in bfd_udp.c.
+
+### Main module
+
+Main module is responsible for handling all the BFD functionality defined
+in RFC 5880.
+
+#### Internal API
+
+Internal APIs defined in bfd_main.h are called from transport-specific code
+to create/modify/delete
+
+#### Packet receipt
+
+When a packet is received by the transport layer, it is forwarded to main
+module (to main thread) via an RPC call. At this point, the authentication has
+been verified, so the packet is consumed, session parameters are updated
+accordingly and state change (if applicable). Based on these, the timeouts
+are adjusted if required and an event is sent to the process node to wake up
+and recalculate sleep time.
+
+#### Packet transmit
+
+Main module allocates a vlib_buffer_t, creates the required BFD frame (control
+or echo in it), then calls the transport layer to add the transport layer.
+Then a frame containing the buffer to the aprropriate node is created
+and enqueued.
+
+#### Process node
+
+Main module implements one process node which is a simple loop. The process
+node gets next timeout from the timer wheel, sleeps until the timeout expires
+and then calls a timeout routine which drives the state machine for each
+session which timed out. The sleep is interrupted externally via vlib event,
+when a session is added or modified in a way which might require timer wheel
+manipulation. In this case the caller inserts the necessary timeout to timer
+wheel and then signals the process node to wake up early, handle possible
+timeouts and recalculate the sleep time again.
+
+#### State machine
+
+Default state of BFD session when created is Down, per RFC 5880. State changes
+to Init, Up or Down based on events like received state from peer and timeouts.
+The session state can be set AdminDown using a binary API, which prevents it
+from going to any other state, until this limitation is removed. This state
+is advertised to peers in slow periodic control frames.
+
+For each session, the following timeouts are maintained:
+
+1. tx timeout - used for sending out control frames
+2. rx timeout - used for detecting session timeout
+3. echo tx timeout - used for sending out echo frames
+3. echo rx timeout - used for detecting session timeout based on echo
+
+These timeouts are maintained in cpu clocks and recalculated when appropriate
+(e.g. rx timeout is bumped when a packet is received, keeping the session
+alive). Only the earliest timeout is inserted into the timer wheel at a time
+and timer wheel events are never deleted, rather spurious events are ignored.
+This allows efficient operation, like not inserting events into timing wheel
+for each packet received or ignoring left-over events in case a bfd session
+gets removed and a new one is recreated with the same session index.
+
+#### Authentication keys management
+
+Authentication keys are managed internally in a pool, with each key tracking
+it's use count. The removal/modification is only allowed if the key is not in
+use.
+
+### UDP module
+
+UDP module is responsible for:
+
+1. public APIs/CLIs to configure BFD over UDP.
+2. support code called by main module to encapsulate/decapsulate BFD packets
+
+This module implements two graph nodes - for consuming ipv4 and ipv6 packets
+target at BFD ports 3874 and 3875.
+
+#### Packet receipt
+
+BFD packet receipt receipt starts in the bfd udp graph nodes. Since the code
+needs to verify IP/UDP header data, it relies on ip4-local (and ip6-local)
+nodes to store pointers to the appropriate headers. First, your discriminator
+is extracted from BFD packet and used to lookup the existing session. In case
+it's zero, the pair of IP addresses and sw_if_index is used to lookup session.
+Then, main module is called to verify the authentication, if present.
+Afterwards a check is made if the IP/UDP headers are correct. If yes, then
+an RPC call is made to the main thread to consume the packet and take action
+upon it.
+
+#### Packet transmission
+
+When process node decides that there is a need to transmit the packet, it
+creates a buffer, fills the BFD frame data in and calls the UDP module to
+add the transport layer. This is a simple operation for the control frames
+consisting of just adding UDP/IP headers based on session data. For echo
+frames, an additional step, looking at the echo-source interface and picking
+and address is performed and if this fails, then the packet cannot be
+transmitted and an error is returned to main thread.
diff --git a/src/vnet/bfd/bfd_main.c b/src/vnet/bfd/bfd_main.c
index d38623c..ea6db1f 100644
--- a/src/vnet/bfd/bfd_main.c
+++ b/src/vnet/bfd/bfd_main.c
@@ -1606,8 +1606,6 @@
   bfd_set_remote_required_min_echo_rx (bm, bs, now,
 				       clib_net_to_host_u32
 				       (pkt->req_min_echo_rx));
-  /* FIXME 6.8.2 */
-  /* FIXME 6.8.4 */
   if (bfd_pkt_get_final (pkt))
     {
       if (BFD_POLL_IN_PROGRESS == bs->poll_state)
@@ -1915,13 +1913,13 @@
 {
 #if WITH_LIBSSL > 0
   bfd_auth_key_t *auth_key = NULL;
-  if (!key_len || key_len > bfd_max_len_for_auth_type (auth_type))
+  if (!key_len || key_len > bfd_max_key_len_for_auth_type (auth_type))
     {
       clib_warning ("Invalid authentication key length for auth_type=%d:%s "
 		    "(key_len=%u, must be "
 		    "non-zero, expected max=%u)",
 		    auth_type, bfd_auth_type_str (auth_type), key_len,
-		    (u32) bfd_max_len_for_auth_type (auth_type));
+		    (u32) bfd_max_key_len_for_auth_type (auth_type));
       return VNET_API_ERROR_INVALID_VALUE;
     }
   if (!bfd_auth_type_supported (auth_type))
diff --git a/src/vnet/bfd/bfd_main.h b/src/vnet/bfd/bfd_main.h
index 3be3694..4d460f4 100644
--- a/src/vnet/bfd/bfd_main.h
+++ b/src/vnet/bfd/bfd_main.h
@@ -37,19 +37,19 @@
 
 typedef struct
 {
-  /* global configuration key ID */
+  /** global configuration key ID */
   u32 conf_key_id;
 
-  /* keeps track of how many sessions reference this key */
+  /** keeps track of how many sessions reference this key */
   u32 use_count;
 
-  /*
+  /**
    * key data directly usable for bfd purposes - already padded with zeroes
    * (so we don't need the actual length)
    */
   u8 key[20];
 
-  /* authentication type for this key */
+  /** authentication type for this key */
   bfd_auth_type_e auth_type;
 } bfd_auth_key_t;
 
@@ -68,152 +68,152 @@
 
 typedef struct bfd_session_s
 {
-  /* index in bfd_main.sessions pool */
+  /** index in bfd_main.sessions pool */
   u32 bs_idx;
 
-  /* session state */
+  /** session state */
   bfd_state_e local_state;
 
-  /* remote session state */
+  /** remote session state */
   bfd_state_e remote_state;
 
-  /* local diagnostics */
+  /** local diagnostics */
   bfd_diag_code_e local_diag;
 
-  /* remote diagnostics */
+  /** remote diagnostics */
   bfd_diag_code_e remote_diag;
 
-  /* local discriminator */
+  /** local discriminator */
   u32 local_discr;
 
-  /* remote discriminator */
+  /** remote discriminator */
   u32 remote_discr;
 
-  /* configured desired min tx interval (microseconds) */
+  /** configured desired min tx interval (microseconds) */
   u32 config_desired_min_tx_usec;
 
-  /* configured desired min tx interval (clocks) */
+  /** configured desired min tx interval (clocks) */
   u64 config_desired_min_tx_clocks;
 
-  /* effective desired min tx interval (clocks) */
+  /** effective desired min tx interval (clocks) */
   u64 effective_desired_min_tx_clocks;
 
-  /* configured required min rx interval (microseconds) */
+  /** configured required min rx interval (microseconds) */
   u32 config_required_min_rx_usec;
 
-  /* configured required min rx interval (clocks) */
+  /** configured required min rx interval (clocks) */
   u64 config_required_min_rx_clocks;
 
-  /* effective required min rx interval (clocks) */
+  /** effective required min rx interval (clocks) */
   u64 effective_required_min_rx_clocks;
 
-  /* remote min rx interval (microseconds) */
+  /** remote min rx interval (microseconds) */
   u64 remote_min_rx_usec;
 
-  /* remote min rx interval (clocks) */
+  /** remote min rx interval (clocks) */
   u64 remote_min_rx_clocks;
 
-  /* remote min echo rx interval (microseconds) */
+  /** remote min echo rx interval (microseconds) */
   u64 remote_min_echo_rx_usec;
 
-  /* remote min echo rx interval (clocks) */
+  /** remote min echo rx interval (clocks) */
   u64 remote_min_echo_rx_clocks;
 
-  /* remote desired min tx interval (clocks) */
+  /** remote desired min tx interval (clocks) */
   u64 remote_desired_min_tx_clocks;
 
-  /* configured detect multiplier */
+  /** configured detect multiplier */
   u8 local_detect_mult;
 
-  /* 1 if remote system sets demand mode, 0 otherwise */
+  /** 1 if remote system sets demand mode, 0 otherwise */
   u8 remote_demand;
 
-  /* remote detect multiplier */
+  /** remote detect multiplier */
   u8 remote_detect_mult;
 
-  /* 1 is echo function is active, 0 otherwise */
+  /** 1 is echo function is active, 0 otherwise */
   u8 echo;
 
-  /* set to value of timer in timing wheel, 0 if never set */
+  /** set to value of timer in timing wheel, 0 if never set */
   u64 wheel_time_clocks;
 
-  /* transmit interval */
+  /** transmit interval */
   u64 transmit_interval_clocks;
 
-  /* next time at which to transmit a packet */
+  /** next time at which to transmit a packet */
   u64 tx_timeout_clocks;
 
-  /* timestamp of last packet transmitted */
+  /** timestamp of last packet transmitted */
   u64 last_tx_clocks;
 
-  /* timestamp of last packet received */
+  /** timestamp of last packet received */
   u64 last_rx_clocks;
 
-  /* transmit interval for echo packets */
+  /** transmit interval for echo packets */
   u64 echo_transmit_interval_clocks;
 
-  /* next time at which to transmit echo packet */
+  /** next time at which to transmit echo packet */
   u64 echo_tx_timeout_clocks;
 
-  /* timestamp of last echo packet transmitted */
+  /** timestamp of last echo packet transmitted */
   u64 echo_last_tx_clocks;
 
-  /* timestamp of last echo packet received */
+  /** timestamp of last echo packet received */
   u64 echo_last_rx_clocks;
 
-  /* secret used for calculating/checking checksum of echo packets */
+  /** secret used for calculating/checking checksum of echo packets */
   u32 echo_secret;
 
-  /* detection time */
+  /** detection time */
   u64 detection_time_clocks;
 
-  /* state info regarding poll sequence */
+  /** state info regarding poll sequence */
   bfd_poll_state_e poll_state;
 
-  /*
+  /**
    * helper for delayed poll sequence - marks either start of running poll
    * sequence or timeout, after which we can start the next poll sequnce
    */
   u64 poll_state_start_or_timeout_clocks;
 
-  /* authentication information */
+  /** authentication information */
   struct
   {
-    /* current key in use */
+    /** current key in use */
     bfd_auth_key_t *curr_key;
 
-    /*
+    /**
      * set to next key to use if delayed switch is enabled - in that case
      * the key is switched when first incoming packet is signed with next_key
      */
     bfd_auth_key_t *next_key;
 
-    /* sequence number incremented occasionally or always (if meticulous) */
+    /** sequence number incremented occasionally or always (if meticulous) */
     u32 local_seq_number;
 
-    /* remote sequence number */
+    /** remote sequence number */
     u32 remote_seq_number;
 
-    /* set to 1 if remote sequence number is known */
+    /** set to 1 if remote sequence number is known */
     u8 remote_seq_number_known;
 
-    /* current key ID sent out in bfd packet */
+    /** current key ID sent out in bfd packet */
     u8 curr_bfd_key_id;
 
-    /* key ID to use when switched to next_key */
+    /** key ID to use when switched to next_key */
     u8 next_bfd_key_id;
 
-    /*
+    /**
      * set to 1 if delayed action is pending, which might be activation
      * of authentication, change of key or deactivation
      */
     u8 is_delayed;
   } auth;
 
-  /* transport type for this session */
+  /** transport type for this session */
   bfd_transport_e transport;
 
-  /* union of transport-specific data */
+  /** union of transport-specific data */
   union
   {
     bfd_udp_session_t udp;
@@ -222,48 +222,48 @@
 
 typedef struct
 {
-  /* pool of bfd sessions context data */
+  /** pool of bfd sessions context data */
   bfd_session_t *sessions;
 
-  /* timing wheel for scheduling timeouts */
+  /** timing wheel for scheduling timeouts */
   timing_wheel_t wheel;
 
-  /* timing wheel inaccuracy, in clocks */
+  /** timing wheel inaccuracy, in clocks */
   u64 wheel_inaccuracy;
 
-  /* hashmap - bfd session by discriminator */
+  /** hashmap - bfd session by discriminator */
   u32 *session_by_disc;
 
-  /* background process node index */
+  /** background process node index */
   u32 bfd_process_node_index;
 
-  /* convenience variables */
+  /** convenience variables */
   vlib_main_t *vlib_main;
   vnet_main_t *vnet_main;
 
-  /* cpu clocks per second */
+  /** cpu clocks per second */
   f64 cpu_cps;
 
-  /* default desired min tx in clocks */
+  /** default desired min tx in clocks */
   u64 default_desired_min_tx_clocks;
 
-  /* minimum required min rx while echo function is active - clocks */
+  /** minimum required min rx while echo function is active - clocks */
   u64 min_required_min_rx_while_echo_clocks;
 
-  /* for generating random numbers */
+  /** for generating random numbers */
   u32 random_seed;
 
-  /* pool of authentication keys */
+  /** pool of authentication keys */
   bfd_auth_key_t *auth_keys;
 
-  /* hashmap - index in pool auth_keys by conf_key_id */
+  /** hashmap - index in pool auth_keys by conf_key_id */
   u32 *auth_key_by_conf_key_id;
 
 } bfd_main_t;
 
 extern bfd_main_t bfd_main;
 
-/* Packet counters */
+/** Packet counters */
 #define foreach_bfd_error(F)               \
   F (NONE, "good bfd packets (processed)") \
   F (BAD, "invalid bfd packets")           \
@@ -277,7 +277,7 @@
     BFD_N_ERROR,
 } bfd_error_t;
 
-/* bfd packet trace capture */
+/** bfd packet trace capture */
 typedef struct
 {
   u32 len;
@@ -291,14 +291,14 @@
   BFD_EVENT_CONFIG_CHANGED,
 } bfd_process_event_e;
 
-/* echo packet structure */
 /* *INDENT-OFF* */
+/** echo packet structure */
 typedef CLIB_PACKED (struct {
-  /* local discriminator */
+  /** local discriminator */
   u32 discriminator;
-  /* expire time of this packet - clocks */
+  /** expire time of this packet - clocks */
   u64 expire_time_clocks;
-  /* checksum - based on discriminator, local secret and expire time */
+  /** checksum - based on discriminator, local secret and expire time */
   u64 checksum;
 }) bfd_echo_pkt_t;
 /* *INDENT-ON* */
@@ -335,10 +335,10 @@
 #define USEC_PER_MS 1000LL
 #define USEC_PER_SECOND (1000 * USEC_PER_MS)
 
-/* default, slow transmission interval for BFD packets, per spec at least 1s */
+/** default, slow transmission interval for BFD packets, per spec at least 1s */
 #define BFD_DEFAULT_DESIRED_MIN_TX_USEC USEC_PER_SECOND
 
-/*
+/**
  * minimum required min rx set locally when echo function is used, per spec
  * should be set to at least 1s
  */
diff --git a/src/vnet/bfd/bfd_protocol.c b/src/vnet/bfd/bfd_protocol.c
index 5deb970..cd51e91 100644
--- a/src/vnet/bfd/bfd_protocol.c
+++ b/src/vnet/bfd/bfd_protocol.c
@@ -12,6 +12,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+/**
+ * @file
+ * @brief BFD protocol implementation
+ */
 #include <vnet/bfd/bfd_protocol.h>
 
 u8
@@ -131,7 +135,7 @@
 #endif
 
 u32
-bfd_max_len_for_auth_type (bfd_auth_type_e auth_type)
+bfd_max_key_len_for_auth_type (bfd_auth_type_e auth_type)
 {
 #define F(t, l, n, s) \
   if (auth_type == t) \
diff --git a/src/vnet/bfd/bfd_protocol.h b/src/vnet/bfd/bfd_protocol.h
index cdbb8fa..210c561 100644
--- a/src/vnet/bfd/bfd_protocol.h
+++ b/src/vnet/bfd/bfd_protocol.h
@@ -40,7 +40,10 @@
 #undef F
 } bfd_auth_type_e;
 
-u32 bfd_max_len_for_auth_type (bfd_auth_type_e auth_type);
+/**
+ * @brief get the maximum length of key data for given auth type
+ */
+u32 bfd_max_key_len_for_auth_type (bfd_auth_type_e auth_type);
 const char *bfd_auth_type_str (bfd_auth_type_e auth_type);
 
 /* *INDENT-OFF* */
diff --git a/src/vnet/bfd/bfd_udp.c b/src/vnet/bfd/bfd_udp.c
index e6dbaab..b3eabc9 100644
--- a/src/vnet/bfd/bfd_udp.c
+++ b/src/vnet/bfd/bfd_udp.c
@@ -12,6 +12,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+/**
+ * @file
+ * @brief BFD UDP transport layer implementation
+ */
 #include <vppinfra/types.h>
 #include <vlibmemory/api.h>
 #include <vlib/vlib.h>
diff --git a/src/vnet/bfd/bfd_udp.h b/src/vnet/bfd/bfd_udp.h
index e33b740..5080ec9 100644
--- a/src/vnet/bfd/bfd_udp.h
+++ b/src/vnet/bfd/bfd_udp.h
@@ -13,7 +13,7 @@
  */
 /**
  * @file
- * @brief BFD global declarations
+ * @brief BFD UDP transport layer declarations
  */
 
 #ifndef __included_bfd_udp_h__
@@ -25,23 +25,27 @@
 #include <vnet/bfd/bfd_api.h>
 
 /* *INDENT-OFF* */
+/** identifier of BFD session based on UDP transport only */
 typedef CLIB_PACKED (struct {
-
+  /** interface to which the session is tied */
   u32 sw_if_index;
+  /** local address */
   ip46_address_t local_addr;
+  /** peer address */
   ip46_address_t peer_addr;
-
 }) bfd_udp_key_t;
 /* *INDENT-ON* */
 
+/** UDP transport specific data embedded in bfd_session's union */
 typedef struct
 {
+  /** key identifying this session */
   bfd_udp_key_t key;
-
+  /** adjacency index returned from adj lock call */
   adj_index_t adj_index;
 } bfd_udp_session_t;
 
-/* bfd udp echo packet trace capture */
+/** bfd udp echo packet trace capture */
 typedef struct
 {
   u32 len;
@@ -50,8 +54,23 @@
 
 struct bfd_session_s;
 
+/**
+ * @brief add the necessary transport layer by prepending it to existing data
+ *
+ * @param is_echo 1 if this is echo packet, 0 if control frame
+ *
+ * @return 1 on success, 0 on failure
+ */
 int bfd_add_udp4_transport (vlib_main_t * vm, vlib_buffer_t * b,
 			    const struct bfd_session_s *bs, int is_echo);
+
+/**
+ * @brief add the necessary transport layer by prepending it to existing data
+ *
+ * @param is_echo 1 if this is echo packet, 0 if control frame
+ *
+ * @return 1 on success, 0 on failure
+ */
 int bfd_add_udp6_transport (vlib_main_t * vm, vlib_buffer_t * b,
 			    const struct bfd_session_s *bs, int is_echo);
 
@@ -62,10 +81,12 @@
  */
 int bfd_udp_is_echo_available (bfd_transport_e transport);
 
-void
-bfd_udp_get_echo_source (int *is_set, u32 * sw_if_index, int *have_usable_ip4,
-			 ip4_address_t * ip4, int *have_usable_ip6,
-			 ip6_address_t * ip6);
+/**
+ * @brief get echo source information - used by CLI
+ */
+void bfd_udp_get_echo_source (int *is_set, u32 * sw_if_index,
+			      int *have_usable_ip4, ip4_address_t * ip4,
+			      int *have_usable_ip6, ip6_address_t * ip6);
 
 #endif /* __included_bfd_udp_h__ */
 
diff --git a/src/vnet/bfd/dir.dox b/src/vnet/bfd/dir.dox
index ed656b5..b9a5978 100644
--- a/src/vnet/bfd/dir.dox
+++ b/src/vnet/bfd/dir.dox
@@ -13,6 +13,6 @@
  * limitations under the License.
  */
 /**
- @dir vnet/vnet/bfd
+ @dir
  @brief Bidirectional Forwarding Detection (BFD) implementation
 */