diff options
author | Neale Ranns <nranns@cisco.com> | 2017-04-05 08:11:14 -0700 |
---|---|---|
committer | Damjan Marion <dmarion.lists@gmail.com> | 2017-04-06 15:18:44 +0000 |
commit | 88fc83eb716bf07f4634de6de5b569f795a56418 (patch) | |
tree | 4c8037b62cb6a57209aef4e28ae273d0ba4e40e7 /src/vnet/bfd | |
parent | 5ee51f8ed616f14f3b32ae8857d383fefa02d861 (diff) |
BFD-FIB interactions
- single-hop BFD: attach a delegate to the appropriate adjacency
- multi-hop BFD [not supported yet]: attach a delegate to the FIB entry.
adjacency/fib_entry state tracks the BFD session state. when the state is down the object does not contribute forwarding hence and hence dependent objects will not use it.
For example, if a route is ECMP via two adjacencies and one of them is BFD down, then only the other is used to forward (i.e. we don't drop half the traffic).
Change-Id: I0ef53e20e73b067001a132cd0a3045408811a822
Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/vnet/bfd')
-rw-r--r-- | src/vnet/bfd/bfd_main.c | 23 | ||||
-rw-r--r-- | src/vnet/bfd/bfd_main.h | 44 | ||||
-rw-r--r-- | src/vnet/bfd/bfd_udp.h | 8 |
3 files changed, 73 insertions, 2 deletions
diff --git a/src/vnet/bfd/bfd_main.c b/src/vnet/bfd/bfd_main.c index 2b70a20c9fd..66b31ce502c 100644 --- a/src/vnet/bfd/bfd_main.c +++ b/src/vnet/bfd/bfd_main.c @@ -101,6 +101,7 @@ bfd_set_defaults (bfd_main_t * bm, bfd_session_t * bs) bs->local_diag = BFD_DIAG_CODE_no_diag; bs->remote_state = BFD_STATE_down; bs->remote_discr = 0; + bs->hop_type = BFD_HOP_TYPE_SINGLE; bs->config_desired_min_tx_usec = BFD_DEFAULT_DESIRED_MIN_TX_USEC; bs->config_desired_min_tx_clocks = bm->default_desired_min_tx_clocks; bs->effective_desired_min_tx_clocks = bm->default_desired_min_tx_clocks; @@ -387,6 +388,17 @@ bfd_set_remote_required_min_echo_rx (bfd_main_t * bm, bfd_session_t * bs, } } +static void +bfd_notify_listeners (bfd_main_t * bm, + bfd_listen_event_e event, const bfd_session_t * bs) +{ + bfd_notify_fn_t *fn; + vec_foreach (fn, bm->listeners) + { + (*fn) (event, bs); + } +} + void bfd_session_start (bfd_main_t * bm, bfd_session_t * bs) { @@ -396,6 +408,7 @@ bfd_session_start (bfd_main_t * bm, bfd_session_t * bs) bfd_recalc_tx_interval (bm, bs); vlib_process_signal_event (bm->vlib_main, bm->bfd_process_node_index, BFD_EVENT_NEW_SESSION, bs->bs_idx); + bfd_notify_listeners (bm, BFD_LISTEN_EVENT_CREATE, bs); } void @@ -533,6 +546,7 @@ bfd_on_state_change (bfd_main_t * bm, bfd_session_t * bs, u64 now, bfd_set_timer (bm, bs, now, handling_wakeup); break; } + bfd_notify_listeners (bm, BFD_LISTEN_EVENT_UPDATE, bs); } static void @@ -1121,6 +1135,14 @@ bfd_hw_interface_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags) VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION (bfd_hw_interface_up_down); +void +bfd_register_listener (bfd_notify_fn_t fn) +{ + bfd_main_t *bm = &bfd_main; + + vec_add1 (bm->listeners, fn); +} + /* * setup function */ @@ -1180,6 +1202,7 @@ bfd_get_session (bfd_main_t * bm, bfd_transport_e t) void bfd_put_session (bfd_main_t * bm, bfd_session_t * bs) { + bfd_notify_listeners (bm, BFD_LISTEN_EVENT_DELETE, bs); if (bs->auth.curr_key) { --bs->auth.curr_key->use_count; diff --git a/src/vnet/bfd/bfd_main.h b/src/vnet/bfd/bfd_main.h index d722a55274c..93adac3dc8d 100644 --- a/src/vnet/bfd/bfd_main.h +++ b/src/vnet/bfd/bfd_main.h @@ -66,6 +66,20 @@ typedef enum #undef F } bfd_poll_state_e; +/** + * hop types + */ +#define foreach_bfd_hop(F) \ + F (SINGLE, "single") \ + F (MULTI, "multi") \ + +typedef enum +{ +#define F(sym, str) BFD_HOP_TYPE_##sym, + foreach_bfd_hop (F) +#undef F +} bfd_hop_type_e; + typedef struct bfd_session_s { /** index in bfd_main.sessions pool */ @@ -77,6 +91,9 @@ typedef struct bfd_session_s /** remote session state */ bfd_state_e remote_state; + /** BFD hop type */ + bfd_hop_type_e hop_type; + /** local diagnostics */ bfd_diag_code_e local_diag; @@ -220,6 +237,26 @@ typedef struct bfd_session_s }; } bfd_session_t; +/** + * listener events + */ +#define foreach_bfd_listen_event(F) \ + F (CREATE, "sesion-created") \ + F (UPDATE, "session-updated") \ + F (DELETE, "session-deleted") + +typedef enum +{ +#define F(sym, str) BFD_LISTEN_EVENT_##sym, + foreach_bfd_listen_event (F) +#undef F +} bfd_listen_event_e; + +/** + * session nitification call back function type + */ +typedef void (*bfd_notify_fn_t) (bfd_listen_event_e, const bfd_session_t *); + typedef struct { /** pool of bfd sessions context data */ @@ -259,6 +296,8 @@ typedef struct /** hashmap - index in pool auth_keys by conf_key_id */ u32 *auth_key_by_conf_key_id; + /** A vector of callback notification functions */ + bfd_notify_fn_t *listeners; } bfd_main_t; extern bfd_main_t bfd_main; @@ -345,6 +384,11 @@ const char *bfd_poll_state_string (bfd_poll_state_e state); */ #define BFD_REQUIRED_MIN_RX_USEC_WHILE_ECHO USEC_PER_SECOND +/** + * Register a callback function to receive session notifications. + */ +void bfd_register_listener (bfd_notify_fn_t fn); + #endif /* __included_bfd_main_h__ */ /* diff --git a/src/vnet/bfd/bfd_udp.h b/src/vnet/bfd/bfd_udp.h index a4adbadf861..87868104f98 100644 --- a/src/vnet/bfd/bfd_udp.h +++ b/src/vnet/bfd/bfd_udp.h @@ -27,8 +27,12 @@ /* *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; + union { + /** interface to which the session is tied - single-hop */ + u32 sw_if_index; + /** the FIB index the peer is in - multi-hop*/ + u32 fib_index; + }; /** local address */ ip46_address_t local_addr; /** peer address */ |