aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/bfd
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2017-04-05 08:11:14 -0700
committerDamjan Marion <dmarion.lists@gmail.com>2017-04-06 15:18:44 +0000
commit88fc83eb716bf07f4634de6de5b569f795a56418 (patch)
tree4c8037b62cb6a57209aef4e28ae273d0ba4e40e7 /src/vnet/bfd
parent5ee51f8ed616f14f3b32ae8857d383fefa02d861 (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.c23
-rw-r--r--src/vnet/bfd/bfd_main.h44
-rw-r--r--src/vnet/bfd/bfd_udp.h8
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 */