X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fadj%2Fadj_bfd.c;h=c1f02dd907321b72f1701c8ddf48aa60ec57b200;hb=ab4d9174d890bff4c07b44957a20eacb33c88172;hp=de7abfe447079a4e2fc1f7a02d3ee1c01cd2668d;hpb=76447a740a6989db08dcd0fcbd066b193a875177;p=vpp.git diff --git a/src/vnet/adj/adj_bfd.c b/src/vnet/adj/adj_bfd.c index de7abfe4470..c1f02dd9073 100644 --- a/src/vnet/adj/adj_bfd.c +++ b/src/vnet/adj/adj_bfd.c @@ -29,6 +29,13 @@ typedef enum adj_bfd_state_t_ ADJ_BFD_STATE_UP, } adj_bfd_state_t; +#define ADJ_BFD_STATES { \ + [ADJ_BFD_STATE_DOWN] = "down", \ + [ADJ_BFD_STATE_UP] = "up", \ +} + +static const char *adj_bfd_state_names[] = ADJ_BFD_STATES; + /** * BFD delegate daa */ @@ -107,9 +114,7 @@ void adj_bfd_notify (bfd_listen_event_e event, const bfd_session_t *session) { - const bfd_udp_key_t *key; adj_bfd_delegate_t *abd; - fib_protocol_t fproto; adj_delegate_t *aed; adj_index_t ai; @@ -122,19 +127,28 @@ adj_bfd_notify (bfd_listen_event_e event, return; } - key = &session->udp.key; - - fproto = (ip46_address_is_ip4 (&key->peer_addr) ? - FIB_PROTOCOL_IP4: - FIB_PROTOCOL_IP6); + switch (session->transport) + { + case BFD_TRANSPORT_UDP4: + case BFD_TRANSPORT_UDP6: + /* + * pick up the same adjacency that the BFD session is using + * to send. The BFD session is holding a lock on this adj. + */ + ai = session->udp.adj_index; + break; + default: + /* + * Don't know what adj this session uses + */ + return; + } - /* - * find the adj that corresponds to the BFD session. - */ - ai = adj_nbr_add_or_lock(fproto, - fib_proto_to_link(fproto), - &key->peer_addr, - key->sw_if_index); + if (INDEX_INVALID == ai) + { + /* No associated Adjacency with the session */ + return; + } switch (event) { @@ -152,35 +166,29 @@ adj_bfd_notify (bfd_listen_event_e event, } else { - /* - * lock the adj. add the delegate. - * Lockinging the adj prevents it being removed and thus maintains - * the BFD derived states - */ - adj_lock(ai); - /* * allocate and init a new delegate struct */ pool_get(abd_pool, abd); /* - * pretend the session is up and skip the walk. - * If we set it down then we get traffic loss on new children. - * if we walk then we lose traffic for existing children. Wait - * for the first BFD UP/DOWN before we let the session's state - * influence forwarding. + * it would be best here if we could ignore this create and just + * wait for the first update, but this is not possible because + * BFD sessions are created in the down state, and can remain this + * way without transitioning to another state if the peer is + * unresponsive. So we have to assume down and wait for up. */ - abd->abd_state = ADJ_BFD_STATE_UP; + abd->abd_state = ADJ_BFD_STATE_DOWN; abd->abd_index = session->bs_idx; adj_delegate_add(adj_get(ai), ADJ_DELEGATE_BFD, abd - abd_pool); + adj_bfd_update_walk(ai); } break; case BFD_LISTEN_EVENT_UPDATE: /* - * state change up/dowm and + * state change up/down and */ abd = adj_bfd_from_base(adj_delegate_get(adj_get(ai), ADJ_DELEGATE_BFD)); @@ -205,14 +213,12 @@ adj_bfd_notify (bfd_listen_event_e event, { /* * has an associated BFD tracking delegate - * remove the BFD tracking deletgate, update children, then - * unlock the adj + * remove the BFD tracking delegate, update children */ adj_delegate_remove(ai, ADJ_DELEGATE_BFD); pool_put(abd_pool, abd); adj_bfd_update_walk(ai); - adj_unlock(ai); } /* * else @@ -220,11 +226,6 @@ adj_bfd_notify (bfd_listen_event_e event, */ break; } - - /* - * unlock match of the add-or-lock at the start - */ - adj_unlock(ai); } int @@ -258,8 +259,8 @@ adj_delegate_fmt_bfd (const adj_delegate_t *aed, u8 *s) { const adj_bfd_delegate_t *abd = adj_bfd_from_const_base(aed); - s = format(s, "BFD:[state:%d index:%d]", - abd->abd_state, + s = format(s, "BFD:[state:%s index:%d]", + adj_bfd_state_names[abd->abd_state], abd->abd_index); return (s); @@ -272,16 +273,16 @@ const static adj_delegate_vft_t adj_delegate_vft = { static clib_error_t * adj_bfd_main_init (vlib_main_t * vm) { - clib_error_t * error = NULL; - - if ((error = vlib_call_init_function (vm, bfd_main_init))) - return (error); - bfd_register_listener(adj_bfd_notify); adj_delegate_register_type (ADJ_DELEGATE_BFD, &adj_delegate_vft); - return (error); + return (0); } -VLIB_INIT_FUNCTION (adj_bfd_main_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (adj_bfd_main_init)= +{ + .runs_after = VLIB_INITS("bfd_main_init"), +}; +/* *INDENT-ON* */