/*
 * Copyright (c) 2011-2016 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @file
 * @brief BFD nodes implementation
 */

#if WITH_LIBSSL > 0
#include <openssl/sha.h>
#endif

#if __SSE4_2__
#include <x86intrin.h>
#endif

#include <vlibmemory/api.h>
#include <vppinfra/random.h>
#include <vppinfra/error.h>
#include <vppinfra/hash.h>
#include <vppinfra/xxhash.h>
#include <vnet/ethernet/ethernet.h>
#include <vnet/ethernet/packet.h>
#include <vnet/bfd/bfd_debug.h>
#include <vnet/bfd/bfd_protocol.h>
#include <vnet/bfd/bfd_main.h>
#include <vlib/log.h>

static u64
bfd_calc_echo_checksum (u32 discriminator, u64 expire_time, u32 secret)
{
  u64 checksum = 0;
#if defined(clib_crc32c_uses_intrinsics) && !defined (__i386__)
  checksum = crc32_u64 (0, discriminator);
  checksum = crc32_u64 (checksum, expire_time);
  checksum = crc32_u64 (checksum, secret);
#else
  checksum = clib_xxhash (discriminator ^ expire_time ^ secret);
#endif
  return checksum;
}

static u64
bfd_usec_to_nsec (u64 us)
{
  return us * NSEC_PER_USEC;
}

u32
bfd_nsec_to_usec (u64 nsec)
{
  return nsec / NSEC_PER_USEC;
}

always_inline u64
bfd_time_now_nsec (vlib_main_t * vm, f64 * vm_time)
{
  f64 _vm_time = vlib_time_now (vm);
  if (vm_time)
    *vm_time = _vm_time;
  return _vm_time * NSEC_PER_SEC;
}

static vlib_node_registration_t bfd_process_node;

u8 *
format_bfd_auth_key (u8 * s, va_list * args)
{
  const bfd_auth_key_t *key = va_arg (*args, bfd_auth_key_t *);
  if (key)
    {
      s = format (s, "{auth-type=%u:%s, conf-key-id=%u, use-count=%u}, ",
		  key->auth_type, bfd_auth_type_str (key->auth_type),
		  key->conf_key_id, key->use_count);
    }
  else
    {
      s = format (s, "{none}");
    }
  return s;
}

/*
 * We actually send all bfd pkts to the "error" node after scanning
 * them, so the graph node has only one next-index. The "error-drop"
 * node automatically bumps our per-node packet counters for us.
 */
typedef enum
{
  BFD_INPUT_NEXT_NORMAL,
  BFD_INPUT_N_NEXT,
} bfd_input_next_t;

static void bfd_on_state_change (bfd_main_t * bm, bfd_session_t * bs, u64 now,
				 int handling_wakeup);

static void
bfd_set_defaults (bfd_main_t * bm, bfd_session_t * bs)
{
  bs->local_state = BFD_STATE_down;
  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_nsec = bm->default_desired_min_tx_nsec;
  bs->effective_desired_min_tx_nsec = bm->default_desired_min_tx_nsec;
  bs->remote_min_rx_usec = 1;
  bs->remote_min_rx_nsec = bfd_usec_to_nsec (bs->remote_min_rx_usec);
  bs->remote_min_echo_rx_usec = 0;
  bs->remote_min_echo_rx_nsec = 0;
  bs->remote_demand = 0;
  bs->auth.remote_seq_number = 0;
  bs->auth.remote_seq_number_known = 0;
  bs->auth.local_seq_number = random_u32 (&bm->random_seed);
  bs->echo_secret = random_u32 (&bm->random_seed);
}

static void
bfd_set_diag (bfd_session_t * bs, bfd_diag_code_e code)
{
  if (bs->local_diag != code)
    {
      BFD_DBG ("set local_diag, bs_idx=%d: '%d:%s'", bs->bs_idx, code,
	       bfd_diag_code_string (code));
      bs->local_diag = code;
    }
}

static void
bfd_set_state (vlib_main_t * vm, bfd_main_t * bm, bfd_session_t * bs,
	       bfd_state_e new_state, int handling_wakeup)
{
  if (bs->local_state != new_state)
    {
      BFD_DBG ("Change state, bs_idx=%d: %s->%s", bs->bs_idx,
	       bfd_state_string (bs->local_state),
	       bfd_state_string (new_state));
      bs->local_state = new_state;
      bfd_on_state_change (bm, bs, bfd_time_now_nsec (vm, NULL),
			   handling_wakeup);
    }
}

const char *
bfd_poll_state_string (bfd_poll_state_e state)
{
  switch (state)
    {
#define F(x)         \
  case BFD_POLL_##x: \
    return "BFD_POLL_" #x;
      foreach_bfd_poll_state (F)
#undef F
    }
  return "UNKNOWN";
}

static void
bfd_set_poll_state (bfd_session_t * bs, bfd_poll_state_e state)
{
  if (bs->poll_state != state)
    {
      BFD_DBG ("Setting poll state=%s, bs_idx=%u",
	       bfd_poll_state_string (state), bs->bs_idx);
      bs->poll_state = state;
    }
}

static void
bfd_recalc_tx_interval (bfd_main_t * bm, bfd_session_t * bs)
{
  bs->transmit_interval_nsec =
    clib_max (bs->effective_desired_min_tx_nsec, bs->remote_min_rx_nsec);
  BFD_DBG ("Recalculated transmit interval " BFD_CLK_FMT,
	   BFD_CLK_PRN (bs->transmit_interval_nsec));
}

static void
bfd_recalc_echo_tx_interval (bfd_main_t * bm, bfd_session_t * bs)
{
  bs->echo_transmit_interval_nsec =
    clib_max (bs->effective_desired_min_tx_nsec, bs->remote_min_echo_rx_nsec);
  BFD_DBG ("Recalculated echo transmit interval " BFD_CLK_FMT,
	   BFD_CLK_PRN (bs->echo_transmit_interval_nsec));
}

static void
bfd_calc_next_tx (bfd_main_t * bm, bfd_session_t * bs, u64 now)
{
  if (bs->local_detect_mult > 1)
    {
      /* common case - 75-100% of transmit interval */
      bs->tx_timeout_nsec = bs->last_tx_nsec +
	(1 - .25 * (random_f64 (&bm->random_seed))) *
	bs->transmit_interval_nsec;
      if (bs->tx_timeout_nsec < now)
	{
	  /*
	   * the timeout is in the past, which means that either remote
	   * demand mode was set or performance/clock issues ...
	   */
	  BFD_DBG ("Missed %lu transmit events (now is %lu, calc "
		   "tx_timeout is %lu)",
		   (now - bs->tx_timeout_nsec) /
		   bs->transmit_interval_nsec, now, bs->tx_timeout_nsec);
	  bs->tx_timeout_nsec = now;
	}
    }
  else
    {
      /* special case - 75-90% of transmit interval */
      bs->tx_timeout_nsec = bs->last_tx_nsec +
	(.9 - .15 * (random_f64 (&bm->random_seed))) *
	bs->transmit_interval_nsec;
      if (bs->tx_timeout_nsec < now)
	{
	  /*
	   * the timeout is in the past, which means that either remote
	   * demand mode was set or performance/clock issues ...
	   */
	  BFD_DBG ("Missed %lu transmit events (now is %lu, calc "
		   "tx_timeout is %lu)",
		   (now - bs->tx_timeout_nsec) /
		   bs->transmit_interval_nsec, now, bs->tx_timeout_nsec);
	  bs->tx_timeout_nsec = now;
	}
    }
  if (bs->tx_timeout_nsec)
    {
      BFD_DBG ("Next transmit in %lu nsec/%.02fs@%lu",
	       bs->tx_timeout_nsec - now,
	       (bs->tx_timeout_nsec - now) * SEC_PER_NSEC,
	       bs->tx_timeout_nsec);
    }
}

static void
bfd_calc_next_echo_tx (bfd_main_t * bm, bfd_session_t * bs, u64 now)
{
  bs->echo_tx_timeout_nsec =
    bs->echo_last_tx_nsec + bs->echo_transmit_interval_nsec;
  if (bs->echo_tx_timeout_nsec < now)
    {
      /* huh, we've missed it already, transmit now */
      BFD_DBG ("Missed %lu echo transmit events (now is %lu, calc tx_timeout "
	       "is %lu)",
	       (now - bs->echo_tx_timeout_nsec) /
	       bs->echo_transmit_interval_nsec,
	       now, bs->echo_tx_timeout_nsec);
      bs->echo_tx_timeout_nsec = now;
    }
  BFD_DBG ("Next echo transmit in %lu nsec/%.02fs@%lu",
	   bs->echo_tx_timeout_nsec - now,
	   (bs->echo_tx_timeout_nsec - now) * SEC_PER_NSEC,
	   bs->echo_tx_timeout_nsec);
}

static void
bfd_recalc_detection_time (bfd_main_t * bm, bfd_session_t * bs)
{
  if (bs->local_state == BFD_STATE_init || bs->local_state == BFD_STATE_up)
    {
      bs->detection_time_nsec =
	bs->remote_detect_mult *
	clib_max (bs->effective_required_min_rx_nsec,
		  bs->remote_desired_min_tx_nsec);
      BFD_DBG ("Recalculated detection time %lu nsec/%.3fs",
	       bs->detection_time_nsec,
	       bs->detection_time_nsec * SEC_PER_NSEC);
    }
}

static void
bfd_set_timer (bfd_main_t * bm, bfd_session_t * bs, u64 now,
	       int handling_wakeup)
{
  u64 next = 0;
  u64 rx_timeout = 0;
  u64 tx_timeout = 0;
  if (BFD_STATE_up == bs->local_state)
    {
      rx_timeout = bs->last_rx_nsec + bs->detection_time_nsec;
    }
  if (BFD_STATE_up != bs->local_state ||
      (!bs->remote_demand && bs->remote_min_rx_usec) ||
      BFD_POLL_NOT_NEEDED != bs->poll_state)
    {
      tx_timeout = bs->tx_timeout_nsec;
    }
  if (tx_timeout && rx_timeout)
    {
      next = clib_min (tx_timeout, rx_timeout);
    }
  else if (tx_timeout)
    {
      next = tx_timeout;
    }
  else if (rx_timeout)
    {
      next = rx_timeout;
    }
  if (bs->echo && next > bs->echo_tx_timeout_nsec)
    {
      next = bs->echo_tx_timeout_nsec;
    }
  BFD_DBG ("bs_idx=%u, tx_timeout=%lu, echo_tx_timeout=%lu, rx_timeout=%lu, "
	   "next=%s",
	   bs->bs_idx, tx_timeout, bs->echo_tx_timeout_nsec, rx_timeout,
	   next == tx_timeout
	   ? "tx" : (next == bs->echo_tx_timeout_nsec ? "echo tx" : "rx"));
  if (next)
    {
      int send_signal = 0;
      bs->event_time_nsec = next;
      /* add extra tick if it's not even */
      u32 wheel_time_ticks =
	(bs->event_time_nsec - now) / bm->nsec_per_tw_tick +
	((bs->event_time_nsec - now) % bm->nsec_per_tw_tick != 0);
      BFD_DBG ("event_time_nsec %lu (%lu nsec/%.3fs in future) -> "
	       "wheel_time_ticks %u", bs->event_time_nsec,
	       bs->event_time_nsec - now,
	       (bs->event_time_nsec - now) * SEC_PER_NSEC, wheel_time_ticks);
      bfd_lock (bm);
      if (bs->tw_id)
	{
	  TW (tw_timer_update) (&bm->wheel, bs->tw_id, wheel_time_ticks);
	  BFD_DBG ("tw_timer_update(%p, %u, %lu);", &bm->wheel, bs->tw_id,
		   wheel_time_ticks);
	}
      else
	{
	  bs->tw_id =
	    TW (tw_timer_start) (&bm->wheel, bs->bs_idx, 0, wheel_time_ticks);
	  BFD_DBG ("tw_timer_start(%p, %u, 0, %lu) == %u;", &bm->wheel,
		   bs->bs_idx, wheel_time_ticks);
	}

      if (!handling_wakeup)
	{

	  /* Send only if it is earlier than current awaited wakeup time */
	  send_signal =
	    (bs->event_time_nsec < bm->bfd_process_next_wakeup_nsec) &&
	    /*
	     * If the wake-up time is within 2x the delay of the event propagation delay,
	     * avoid the expense of sending the event. The 2x multiplier is to workaround the race whereby
	     * simultaneous event + expired timer create one recurring bogus wakeup/suspend instance,
	     * due to double scheduling of the node on the pending list.
	     */
	    (bm->bfd_process_next_wakeup_nsec - bs->event_time_nsec >
	     2 * bm->bfd_process_wakeup_event_delay_nsec) &&
	    /* Must be no events in flight to send an event */
	    (!bm->bfd_process_wakeup_events_in_flight);

	  /* If we do send the signal, note this down along with the start timestamp */
	  if (send_signal)
	    {
	      bm->bfd_process_wakeup_events_in_flight++;
	      bm->bfd_process_wakeup_event_start_nsec = now;
	    }
	}
      bfd_unlock (bm);

      /* Use the multithreaded event sending so the workers can send events too */
      if (send_signal)
	{
	  vlib_process_signal_event_mt (bm->vlib_main,
					bm->bfd_process_node_index,
					BFD_EVENT_RESCHEDULE, ~0);
	}
    }
}

static void
bfd_set_effective_desired_min_tx (bfd_main_t * bm,
				  bfd_session_t * bs, u64 now,
				  u64 desired_min_tx_nsec)
{
  bs->effective_desired_min_tx_nsec = desired_min_tx_nsec;
  BFD_DBG ("Set effective desired min tx to " BFD_CLK_FMT,
	   BFD_CLK_PRN (bs->effective_desired_min_tx_nsec));
  bfd_recalc_detection_time (bm, bs);
  bfd_recalc_tx_interval (bm, bs);
  bfd_recalc_echo_tx_interval (bm, bs);
  bfd_calc_next_tx (bm, bs, now);
}

static void
bfd_set_effective_required_min_rx (bfd_main_t * bm,
				   bfd_session_t * bs,
				   u64 required_min_rx_nsec)
{
  bs->effective_required_min_rx_nsec = required_min_rx_nsec;
  BFD_DBG ("Set effective required min rx to " BFD_CLK_FMT,
	   BFD_CLK_PRN (bs->effective_required_min_rx_nsec));
  bfd_recalc_detection_time (bm, bs);
}

static void
bfd_set_remote_required_min_rx (bfd_main_t * bm, bfd_session_t * bs,
				u64 now, u32 remote_required_min_rx_usec)
{
  if (bs->remote_min_rx_usec != remote_required_min_rx_usec)
    {
      bs->remote_min_rx_usec = remote_required_min_rx_usec;
      bs->remote_min_rx_nsec = bfd_usec_to_nsec (remote_required_min_rx_usec);
      BFD_DBG ("Set remote min rx to " BFD_CLK_FMT,
	       BFD_CLK_PRN (bs->remote_min_rx_nsec));
      bfd_recalc_detection_time (bm, bs);
      bfd_recalc_tx_interval (bm, bs);
    }
}

static void
bfd_set_remote_required_min_echo_rx (bfd_main_t * bm, bfd_session_t * bs,
				     u64 now,
				     u32 remote_required_min_echo_rx_usec)
{
  if (bs->remote_min_echo_rx_usec != remote_required_min_echo_rx_usec)
    {
      bs->remote_min_echo_rx_usec = remote_required_min_echo_rx_usec;
      bs->remote_min_echo_rx_nsec =
	bfd_usec_to_nsec (bs->remote_min_echo_rx_usec);
      BFD_DBG ("Set remote min echo rx to " BFD_CLK_FMT,
	       BFD_CLK_PRN (bs->remote_min_echo_rx_nsec));
      bfd_recalc_echo_tx_interval (bm, 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)
{
  BFD_DBG ("\nStarting session: %U", format_bfd_session, bs);
  vlib_log_info (bm->log_class, "start BFD session: %U",
		 format_bfd_session_brief, bs);
  bfd_set_effective_required_min_rx (bm, bs, bs->config_required_min_rx_nsec);
  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
bfd_session_set_flags (vlib_main_t * vm, bfd_session_t * bs, u8 admin_up_down)
{
  bfd_main_t *bm = &bfd_main;
  u64 now = bfd_time_now_nsec (vm, NULL);
  if (admin_up_down)
    {
      BFD_DBG ("Session set admin-up, bs-idx=%u", bs->bs_idx);
      vlib_log_info (bm->log_class, "set session admin-up: %U",
		     format_bfd_session_brief, bs);
      bfd_set_state (vm, bm, bs, BFD_STATE_down, 0);
      bfd_set_diag (bs, BFD_DIAG_CODE_no_diag);
      bfd_calc_next_tx (bm, bs, now);
      bfd_set_timer (bm, bs, now, 0);
    }
  else
    {
      BFD_DBG ("Session set admin-down, bs-idx=%u", bs->bs_idx);
      vlib_log_info (bm->log_class, "set session admin-down: %U",
		     format_bfd_session_brief, bs);
      bfd_set_diag (bs, BFD_DIAG_CODE_admin_down);
      bfd_set_state (vm, bm, bs, BFD_STATE_admin_down, 0);
      bfd_calc_next_tx (bm, bs, now);
      bfd_set_timer (bm, bs, now, 0);
    }
}

u8 *
bfd_input_format_trace (u8 * s, va_list * args)
{
  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
  const bfd_input_trace_t *t = va_arg (*args, bfd_input_trace_t *);
  const bfd_pkt_t *pkt = (bfd_pkt_t *) t->data;
  if (t->len > STRUCT_SIZE_OF (bfd_pkt_t, head))
    {
      s = format (s, "BFD v%u, diag=%u(%s), state=%u(%s),\n"
		  "    flags=(P:%u, F:%u, C:%u, A:%u, D:%u, M:%u), "
		  "detect_mult=%u, length=%u\n",
		  bfd_pkt_get_version (pkt), bfd_pkt_get_diag_code (pkt),
		  bfd_diag_code_string (bfd_pkt_get_diag_code (pkt)),
		  bfd_pkt_get_state (pkt),
		  bfd_state_string (bfd_pkt_get_state (pkt)),
		  bfd_pkt_get_poll (pkt), bfd_pkt_get_final (pkt),
		  bfd_pkt_get_control_plane_independent (pkt),
		  bfd_pkt_get_auth_present (pkt), bfd_pkt_get_demand (pkt),
		  bfd_pkt_get_multipoint (pkt), pkt->head.detect_mult,
		  pkt->head.length);
      if (t->len >= sizeof (bfd_pkt_t) &&
	  pkt->head.length >= sizeof (bfd_pkt_t))
	{
	  s = format (s, "    my discriminator: %u\n",
		      clib_net_to_host_u32 (pkt->my_disc));
	  s = format (s, "    your discriminator: %u\n",
		      clib_net_to_host_u32 (pkt->your_disc));
	  s = format (s, "    desired min tx interval: %u\n",
		      clib_net_to_host_u32 (pkt->des_min_tx));
	  s = format (s, "    required min rx interval: %u\n",
		      clib_net_to_host_u32 (pkt->req_min_rx));
	  s = format (s, "    required min echo rx interval: %u",
		      clib_net_to_host_u32 (pkt->req_min_echo_rx));
	}
      if (t->len >= sizeof (bfd_pkt_with_common_auth_t) &&
	  pkt->head.length >= sizeof (bfd_pkt_with_common_auth_t) &&
	  bfd_pkt_get_auth_present (pkt))
	{
	  const bfd_pkt_with_common_auth_t *with_auth = (void *) pkt;
	  const bfd_auth_common_t *common = &with_auth->common_auth;
	  s = format (s, "\n    auth len: %u\n", common->len);
	  s = format (s, "    auth type: %u:%s\n", common->type,
		      bfd_auth_type_str (common->type));
	  if (t->len >= sizeof (bfd_pkt_with_sha1_auth_t) &&
	      pkt->head.length >= sizeof (bfd_pkt_with_sha1_auth_t) &&
	      (BFD_AUTH_TYPE_keyed_sha1 == common->type ||
	       BFD_AUTH_TYPE_meticulous_keyed_sha1 == common->type))
	    {
	      const bfd_pkt_with_sha1_auth_t *with_sha1 = (void *) pkt;
	      const bfd_auth_sha1_t *sha1 = &with_sha1->sha1_auth;
	      s = format (s, "    seq num: %u\n",
			  clib_net_to_host_u32 (sha1->seq_num));
	      s = format (s, "    key id: %u\n", sha1->key_id);
	      s = format (s, "    hash: %U", format_hex_bytes, sha1->hash,
			  sizeof (sha1->hash));
	    }
	}
      else
	{
	  s = format (s, "\n");
	}
    }

  return s;
}

typedef struct
{
  u32 bs_idx;
} bfd_rpc_event_t;

static void
bfd_rpc_event_cb (const bfd_rpc_event_t * a)
{
  bfd_main_t *bm = &bfd_main;
  u32 bs_idx = a->bs_idx;
  u32 valid_bs = 0;
  bfd_session_t session_data;

  bfd_lock (bm);
  if (!pool_is_free_index (bm->sessions, bs_idx))
    {
      bfd_session_t *bs = pool_elt_at_index (bm->sessions, bs_idx);
      clib_memcpy (&session_data, bs, sizeof (bfd_session_t));
      valid_bs = 1;
    }
  else
    {
      BFD_DBG ("Ignoring event RPC for non-existent session index %u",
	       bs_idx);
    }
  bfd_unlock (bm);

  if (valid_bs)
    bfd_event (bm, &session_data);
}

static void
bfd_event_rpc (u32 bs_idx)
{
  const u32 data_size = sizeof (bfd_rpc_event_t);
  u8 data[data_size];
  bfd_rpc_event_t *event = (bfd_rpc_event_t *) data;

  event->bs_idx = bs_idx;
  vl_api_rpc_call_main_thread (bfd_rpc_event_cb, data, data_size);
}

typedef struct
{
  u32 bs_idx;
} bfd_rpc_notify_listeners_t;

static void
bfd_rpc_notify_listeners_cb (const bfd_rpc_notify_listeners_t * a)
{
  bfd_main_t *bm = &bfd_main;
  u32 bs_idx = a->bs_idx;
  bfd_lock (bm);
  if (!pool_is_free_index (bm->sessions, bs_idx))
    {
      bfd_session_t *bs = pool_elt_at_index (bm->sessions, bs_idx);
      bfd_notify_listeners (bm, BFD_LISTEN_EVENT_UPDATE, bs);
    }
  else
    {
      BFD_DBG ("Ignoring notify RPC for non-existent session index %u",
	       bs_idx);
    }
  bfd_unlock (bm);
}

static void
bfd_notify_listeners_rpc (u32 bs_idx)
{
  const u32 data_size = sizeof (bfd_rpc_notify_listeners_t);
  u8 data[data_size];
  bfd_rpc_notify_listeners_t *notify = (bfd_rpc_notify_listeners_t *) data;
  notify->bs_idx = bs_idx;
  vl_api_rpc_call_main_thread (bfd_rpc_notify_listeners_cb, data, data_size);
}

static void
bfd_on_state_change (bfd_main_t * bm, bfd_session_t * bs, u64 now,
		     int handling_wakeup)
{
  BFD_DBG ("\nState changed: %U", format_bfd_session, bs);

  if (vlib_get_thread_index () == 0)
    {
      bfd_event (bm, bs);
    }
  else
    {
      /* without RPC - a REGRESSION: BFD event are not propagated */
      bfd_event_rpc (bs->bs_idx);
    }

  switch (bs->local_state)
    {
    case BFD_STATE_admin_down:
      bs->echo = 0;
      bfd_set_effective_desired_min_tx (bm, bs, now,
					clib_max
					(bs->config_desired_min_tx_nsec,
					 bm->default_desired_min_tx_nsec));
      bfd_set_effective_required_min_rx (bm, bs,
					 bs->config_required_min_rx_nsec);
      bfd_set_timer (bm, bs, now, handling_wakeup);
      break;
    case BFD_STATE_down:
      bs->echo = 0;
      bfd_set_effective_desired_min_tx (bm, bs, now,
					clib_max
					(bs->config_desired_min_tx_nsec,
					 bm->default_desired_min_tx_nsec));
      bfd_set_effective_required_min_rx (bm, bs,
					 bs->config_required_min_rx_nsec);
      bfd_set_timer (bm, bs, now, handling_wakeup);
      break;
    case BFD_STATE_init:
      bs->echo = 0;
      bfd_set_effective_desired_min_tx (bm, bs, now,
					bs->config_desired_min_tx_nsec);
      bfd_set_timer (bm, bs, now, handling_wakeup);
      break;
    case BFD_STATE_up:
      bfd_set_effective_desired_min_tx (bm, bs, now,
					bs->config_desired_min_tx_nsec);
      if (BFD_POLL_NOT_NEEDED == bs->poll_state)
	{
	  bfd_set_effective_required_min_rx (bm, bs,
					     bs->config_required_min_rx_nsec);
	}
      bfd_set_timer (bm, bs, now, handling_wakeup);
      break;
    }
  if (vlib_get_thread_index () == 0)
    {
      bfd_notify_listeners (bm, BFD_LISTEN_EVENT_UPDATE, bs);
    }
  else
    {
      /* without RPC - a REGRESSION: state changes are not propagated */
      bfd_notify_listeners_rpc (bs->bs_idx);
    }
}

static void
bfd_on_config_change (vlib_main_t * vm, vlib_node_runtime_t * rt,
		      bfd_main_t * bm, bfd_session_t * bs, u64 now)
{
  /*
   * if remote demand mode is set and we need to do a poll, set the next
   * timeout so that the session wakes up immediately
   */
  if (bs->remote_demand && BFD_POLL_NEEDED == bs->poll_state &&
      bs->poll_state_start_or_timeout_nsec < now)
    {
      bs->tx_timeout_nsec = now;
    }
  bfd_recalc_detection_time (bm, bs);
  bfd_set_timer (bm, bs, now, 0);
}

static void
bfd_add_transport_layer (vlib_main_t * vm, u32 bi, bfd_session_t * bs)
{
  switch (bs->transport)
    {
    case BFD_TRANSPORT_UDP4:
      BFD_DBG ("Transport bfd via udp4, bs_idx=%u", bs->bs_idx);
      bfd_add_udp4_transport (vm, bi, bs, 0 /* is_echo */ );
      break;
    case BFD_TRANSPORT_UDP6:
      BFD_DBG ("Transport bfd via udp6, bs_idx=%u", bs->bs_idx);
      bfd_add_udp6_transport (vm, bi, bs, 0 /* is_echo */ );
      break;
    }
}

static int
bfd_transport_control_frame (vlib_main_t * vm, u32 bi, bfd_session_t * bs)
{
  switch (bs->transport)
    {
    case BFD_TRANSPORT_UDP4:
      BFD_DBG ("Transport bfd via udp4, bs_idx=%u", bs->bs_idx);
      return bfd_transport_udp4 (vm, bi, bs);
      break;
    case BFD_TRANSPORT_UDP6:
      BFD_DBG ("Transport bfd via udp6, bs_idx=%u", bs->bs_idx);
      return bfd_transport_udp6 (vm, bi, bs);
      break;
    }
  return 0;
}

static int
bfd_echo_add_transport_layer (vlib_main_t * vm, u32 bi, bfd_session_t * bs)
{
  switch (bs->transport)
    {
    case BFD_TRANSPORT_UDP4:
      BFD_DBG ("Transport bfd echo via udp4, bs_idx=%u", bs->bs_idx);
      return bfd_add_udp4_transport (vm, bi, bs, 1 /* is_echo */ );
      break;
    case BFD_TRANSPORT_UDP6:
      BFD_DBG ("Transport bfd echo via udp6, bs_idx=%u", bs->bs_idx);
      return bfd_add_udp6_transport (vm, bi, bs, 1 /* is_echo */ );
      break;
    }
  return 0;
}

static int
bfd_transport_echo (vlib_main_t * vm, u32 bi, bfd_session_t * bs)
{
  switch (bs->transport)
    {
    case BFD_TRANSPORT_UDP4:
      BFD_DBG ("Transport bfd echo via udp4, bs_idx=%u", bs->bs_idx);
      return bfd_transport_udp4 (vm, bi, bs);
      break;
    case BFD_TRANSPORT_UDP6:
      BFD_DBG ("Transport bfd echo via udp6, bs_idx=%u", bs->bs_idx);
      return bfd_transport_udp6 (vm, bi, bs);
      break;
    }
  return 0;
}

#if WITH_LIBSSL > 0
static void
bfd_add_sha1_auth_section (vlib_buffer_t * b, bfd_session_t * bs)
{
  bfd_pkt_with_sha1_auth_t *pkt = vlib_buffer_get_current (b);
  bfd_auth_sha1_t *auth = &pkt->sha1_auth;
  b->current_length += sizeof (*auth);
  pkt->pkt.head.length += sizeof (*auth);
  bfd_pkt_set_auth_present (&pkt->pkt);
  clib_memset (auth, 0, sizeof (*auth));
  auth->type_len.type = bs->auth.curr_key->auth_type;
  /*
   * only meticulous authentication types require incrementing seq number
   * for every message, but doing so doesn't violate the RFC
   */
  ++bs->auth.local_seq_number;
  auth->type_len.len = sizeof (bfd_auth_sha1_t);
  auth->key_id = bs->auth.curr_bfd_key_id;
  auth->seq_num = clib_host_to_net_u32 (bs->auth.local_seq_number);
  /*
   * first copy the password into the packet, then calculate the hash
   * and finally replace the password with the calculated hash
   */
  clib_memcpy (auth->hash, bs->auth.curr_key->key,
	       sizeof (bs->auth.curr_key->key));
  unsigned char hash[sizeof (auth->hash)];
  SHA1 ((unsigned char *) pkt, sizeof (*pkt), hash);
  BFD_DBG ("hashing: %U", format_hex_bytes, pkt, sizeof (*pkt));
  clib_memcpy (auth->hash, hash, sizeof (hash));
}
#endif

static void
bfd_add_auth_section (vlib_buffer_t * b, bfd_session_t * bs)
{
  bfd_main_t *bm = &bfd_main;
  if (bs->auth.curr_key)
    {
      const bfd_auth_type_e auth_type = bs->auth.curr_key->auth_type;
      switch (auth_type)
	{
	case BFD_AUTH_TYPE_reserved:
	  /* fallthrough */
	case BFD_AUTH_TYPE_simple_password:
	  /* fallthrough */
	case BFD_AUTH_TYPE_keyed_md5:
	  /* fallthrough */
	case BFD_AUTH_TYPE_meticulous_keyed_md5:
	  vlib_log_crit (bm->log_class,
			 "internal error, unexpected BFD auth type '%d'",
			 auth_type);
	  break;
#if WITH_LIBSSL > 0
	case BFD_AUTH_TYPE_keyed_sha1:
	  /* fallthrough */
	case BFD_AUTH_TYPE_meticulous_keyed_sha1:
	  bfd_add_sha1_auth_section (b, bs);
	  break;
#else
	case BFD_AUTH_TYPE_keyed_sha1:
	  /* fallthrough */
	case BFD_AUTH_TYPE_meticulous_keyed_sha1:
	  vlib_log_crit (bm->log_class,
			 "internal error, unexpected BFD auth type '%d'",
			 auth_type);
	  break;
#endif
	}
    }
}

static int
bfd_is_echo_possible (bfd_session_t * bs)
{
  if (BFD_STATE_up == bs->local_state && BFD_STATE_up == bs->remote_state &&
      bs->remote_min_echo_rx_usec > 0)
    {
      switch (bs->transport)
	{
	case BFD_TRANSPORT_UDP4:
	  return bfd_udp_is_echo_available (BFD_TRANSPORT_UDP4);
	case BFD_TRANSPORT_UDP6:
	  return bfd_udp_is_echo_available (BFD_TRANSPORT_UDP6);
	}
    }
  return 0;
}

static void
bfd_init_control_frame (bfd_main_t * bm, bfd_session_t * bs,
			vlib_buffer_t * b)
{
  bfd_pkt_t *pkt = vlib_buffer_get_current (b);
  u32 bfd_length = 0;
  bfd_length = sizeof (bfd_pkt_t);
  clib_memset (pkt, 0, sizeof (*pkt));
  bfd_pkt_set_version (pkt, 1);
  bfd_pkt_set_diag_code (pkt, bs->local_diag);
  bfd_pkt_set_state (pkt, bs->local_state);
  pkt->head.detect_mult = bs->local_detect_mult;
  pkt->head.length = bfd_length;
  pkt->my_disc = bs->local_discr;
  pkt->your_disc = bs->remote_discr;
  pkt->des_min_tx = clib_host_to_net_u32 (bs->config_desired_min_tx_usec);
  if (bs->echo)
    {
      pkt->req_min_rx =
	clib_host_to_net_u32 (bfd_nsec_to_usec
			      (bs->effective_required_min_rx_nsec));
    }
  else
    {
      pkt->req_min_rx =
	clib_host_to_net_u32 (bs->config_required_min_rx_usec);
    }
  pkt->req_min_echo_rx = clib_host_to_net_u32 (1);
  b->current_length = bfd_length;
}

static void
bfd_send_echo (vlib_main_t * vm, vlib_node_runtime_t * rt,
	       bfd_main_t * bm, bfd_session_t * bs, u64 now)
{
  if (!bfd_is_echo_possible (bs))
    {
      BFD_DBG ("\nSwitching off echo function: %U", format_bfd_session, bs);
      bs->echo = 0;
      return;
    }
  if (now >= bs->echo_tx_timeout_nsec)
    {
      BFD_DBG ("\nSending echo packet: %U", format_bfd_session, bs);
      u32 bi;
      if (vlib_buffer_alloc (vm, &bi, 1) != 1)
	{
	  vlib_log_crit (bm->log_class, "buffer allocation failure");
	  return;
	}
      vlib_buffer_t *b = vlib_get_buffer (vm, bi);
      ASSERT (b->current_data == 0);
      VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b);
      bfd_echo_pkt_t *pkt = vlib_buffer_get_current (b);
      clib_memset (pkt, 0, sizeof (*pkt));
      pkt->discriminator = bs->local_discr;
      pkt->expire_time_nsec =
	now + bs->echo_transmit_interval_nsec * bs->local_detect_mult;
      pkt->checksum =
	bfd_calc_echo_checksum (bs->local_discr, pkt->expire_time_nsec,
				bs->echo_secret);
      b->current_length = sizeof (*pkt);
      if (!bfd_echo_add_transport_layer (vm, bi, bs))
	{
	  BFD_ERR ("cannot send echo packet out, turning echo off");
	  bs->echo = 0;
	  vlib_buffer_free_one (vm, bi);
	  return;
	}
      if (!bfd_transport_echo (vm, bi, bs))
	{
	  BFD_ERR ("cannot send echo packet out, turning echo off");
	  bs->echo = 0;
	  vlib_buffer_free_one (vm, bi);
	  return;
	}
      bs->echo_last_tx_nsec = now;
      bfd_calc_next_echo_tx (bm, bs, now);
    }
  else
    {
      BFD_DBG
	("No need to send echo packet now, now is %lu, tx_timeout is %lu",
	 now, bs->echo_tx_timeout_nsec);
    }
}

static void
bfd_send_periodic (vlib_main_t * vm, vlib_node_runtime_t * rt,
		   bfd_main_t * bm, bfd_session_t * bs, u64 now)
{
  if (!bs->remote_min_rx_usec && BFD_POLL_NOT_NEEDED == bs->poll_state)
    {
      BFD_DBG ("Remote min rx interval is zero, not sending periodic control "
	       "frame");
      return;
    }
  if (BFD_POLL_NOT_NEEDED == bs->poll_state && bs->remote_demand &&
      BFD_STATE_up == bs->local_state && BFD_STATE_up == bs->remote_state)
    {
      /*
       * A system MUST NOT periodically transmit BFD Control packets if Demand
       * mode is active on the remote system (bfd.RemoteDemandMode is 1,
       * bfd.SessionState is Up, and bfd.RemoteSessionState is Up) and a Poll
       * Sequence is not being transmitted.
       */
      BFD_DBG ("Remote demand is set, not sending periodic control frame");
      return;
    }
  if (now >= bs->tx_timeout_nsec)
    {
      BFD_DBG ("\nSending periodic control frame: %U", format_bfd_session,
	       bs);
      u32 bi;
      if (vlib_buffer_alloc (vm, &bi, 1) != 1)
	{
	  vlib_log_crit (bm->log_class, "buffer allocation failure");
	  return;
	}
      vlib_buffer_t *b = vlib_get_buffer (vm, bi);
      ASSERT (b->current_data == 0);
      VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b);
      bfd_init_control_frame (bm, bs, b);
      switch (bs->poll_state)
	{
	case BFD_POLL_NEEDED:
	  if (now < bs->poll_state_start_or_timeout_nsec)
	    {
	      BFD_DBG ("Cannot start a poll sequence yet, need to wait for "
		       BFD_CLK_FMT,
		       BFD_CLK_PRN (bs->poll_state_start_or_timeout_nsec -
				    now));
	      break;
	    }
	  bs->poll_state_start_or_timeout_nsec = now;
	  bfd_set_poll_state (bs, BFD_POLL_IN_PROGRESS);
	  /* fallthrough */
	case BFD_POLL_IN_PROGRESS:
	case BFD_POLL_IN_PROGRESS_AND_QUEUED:
	  bfd_pkt_set_poll (vlib_buffer_get_current (b));
	  BFD_DBG ("Setting poll bit in packet, bs_idx=%u", bs->bs_idx);
	  break;
	case BFD_POLL_NOT_NEEDED:
	  /* fallthrough */
	  break;
	}
      bfd_add_auth_section (b, bs);
      bfd_add_transport_layer (vm, bi, bs);
      if (!bfd_transport_control_frame (vm, bi, bs))
	{
	  vlib_buffer_free_one (vm, bi);
	}
      bs->last_tx_nsec = now;
      bfd_calc_next_tx (bm, bs, now);
    }
  else
    {
      BFD_DBG
	("No need to send control frame now, now is %lu, tx_timeout is %lu",
	 now, bs->tx_timeout_nsec);
    }
}

void
bfd_init_final_control_frame (vlib_main_t * vm, vlib_buffer_t * b,
			      bfd_main_t * bm, bfd_session_t * bs,
			      int is_local)
{
  BFD_DBG ("Send final control frame for bs_idx=%lu", bs->bs_idx);
  bfd_init_control_frame (bm, bs, b);
  bfd_pkt_set_final (vlib_buffer_get_current (b));
  bfd_add_auth_section (b, bs);
  u32 bi = vlib_get_buffer_index (vm, b);
  bfd_add_transport_layer (vm, bi, bs);
  bs->last_tx_nsec = bfd_time_now_nsec (vm, NULL);
  /*
   * RFC allows to include changes in final frame, so if there were any
   * pending, we already did that, thus we can clear any pending poll needs
   */
  bfd_set_poll_state (bs, BFD_POLL_NOT_NEEDED);
}

static void
bfd_check_rx_timeout (vlib_main_t * vm, bfd_main_t * bm, bfd_session_t * bs,
		      u64 now, int handling_wakeup)
{
  if (bs->last_rx_nsec + bs->detection_time_nsec <= now)
    {
      BFD_DBG ("Rx timeout, session goes down");
      /*
       * RFC 5880 6.8.1. State Variables

       * bfd.RemoteDiscr

       * The remote discriminator for this BFD session.  This is the
       * discriminator chosen by the remote system, and is totally opaque
       * to the local system.  This MUST be initialized to zero.  If a
       * period of a Detection Time passes without the receipt of a valid,
       * authenticated BFD packet from the remote system, this variable
       * MUST be set to zero.
       */
      bs->remote_discr = 0;
      bfd_set_diag (bs, BFD_DIAG_CODE_det_time_exp);
      bfd_set_state (vm, bm, bs, BFD_STATE_down, handling_wakeup);
      /*
       * If the remote system does not receive any
       * BFD Control packets for a Detection Time, it SHOULD reset
       * bfd.RemoteMinRxInterval to its initial value of 1 (per section 6.8.1,
       * since it is no longer required to maintain previous session state)
       * and then can transmit at its own rate.
       */
      bfd_set_remote_required_min_rx (bm, bs, now, 1);
    }
  else if (bs->echo
	   && bs->echo_last_rx_nsec +
	   bs->echo_transmit_interval_nsec * bs->local_detect_mult <= now)
    {
      BFD_DBG ("Echo rx timeout, session goes down");
      bfd_set_diag (bs, BFD_DIAG_CODE_echo_failed);
      bfd_set_state (vm, bm, bs, BFD_STATE_down, handling_wakeup);
    }
}

void
bfd_on_timeout (vlib_main_t * vm, vlib_node_runtime_t * rt, bfd_main_t * bm,
		bfd_session_t * bs, u64 now)
{
  BFD_DBG ("Timeout for bs_idx=%lu", bs->bs_idx);
  switch (bs->local_state)
    {
    case BFD_STATE_admin_down:
      bfd_send_periodic (vm, rt, bm, bs, now);
      break;
    case BFD_STATE_down:
      bfd_send_periodic (vm, rt, bm, bs, now);
      break;
    case BFD_STATE_init:
      bfd_check_rx_timeout (vm, bm, bs, now, 1);
      bfd_send_periodic (vm, rt, bm, bs, now);
      break;
    case BFD_STATE_up:
      bfd_check_rx_timeout (vm, bm, bs, now, 1);
      if (BFD_POLL_NOT_NEEDED == bs->poll_state && !bs->echo &&
	  bfd_is_echo_possible (bs))
	{
	  /* switch on echo function as main detection method now */
	  BFD_DBG ("Switching on echo function, bs_idx=%u", bs->bs_idx);
	  bs->echo = 1;
	  bs->echo_last_rx_nsec = now;
	  bs->echo_tx_timeout_nsec = now;
	  bfd_set_effective_required_min_rx (bm, bs,
					     clib_max
					     (bm->min_required_min_rx_while_echo_nsec,
					      bs->config_required_min_rx_nsec));
	  bfd_set_poll_state (bs, BFD_POLL_NEEDED);
	}
      bfd_send_periodic (vm, rt, bm, bs, now);
      if (bs->echo)
	{
	  bfd_send_echo (vm, rt, bm, bs, now);
	}
      break;
    }
}

/*
 * bfd process node function
 */
static uword
bfd_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
{
  bfd_main_t *bm = &bfd_main;
  u32 *expired = 0;
  uword event_type, *event_data = 0;

  /* So we can send events to the bfd process */
  bm->bfd_process_node_index = bfd_process_node.index;

  while (1)
    {
      f64 vm_time;
      u64 now = bfd_time_now_nsec (vm, &vm_time);
      BFD_DBG ("wakeup, now is %llunsec, vlib_time_now() is %.9f", now,
	       vm_time);
      bfd_lock (bm);
      f64 timeout;
      if (pool_elts (bm->sessions))
	{
	  u32 first_expires_in_ticks =
	    TW (tw_timer_first_expires_in_ticks) (&bm->wheel);
	  if (!first_expires_in_ticks)
	    {
	      BFD_DBG
		("tw_timer_first_expires_in_ticks(%p) returns 0ticks",
		 &bm->wheel);
	      timeout = bm->wheel.next_run_time - vm_time;
	      BFD_DBG ("wheel.next_run_time is %.9f",
		       bm->wheel.next_run_time);
	      u64 next_expire_nsec = now + timeout * SEC_PER_NSEC;
	      bm->bfd_process_next_wakeup_nsec = next_expire_nsec;
	      bfd_unlock (bm);
	    }
	  else
	    {
	      BFD_DBG ("tw_timer_first_expires_in_ticks(%p) returns %luticks",
		       &bm->wheel, first_expires_in_ticks);
	      u64 next_expire_nsec =
		now + first_expires_in_ticks * bm->nsec_per_tw_tick;
	      bm->bfd_process_next_wakeup_nsec = next_expire_nsec;
	      bfd_unlock (bm);
	      timeout = (next_expire_nsec - now) * SEC_PER_NSEC;
	    }
	  BFD_DBG ("vlib_process_wait_for_event_or_clock(vm, %.09f)",
		   timeout);
	  (void) vlib_process_wait_for_event_or_clock (vm, timeout);
	}
      else
	{
	  (void) vlib_process_wait_for_event (vm);
	}
      event_type = vlib_process_get_events (vm, &event_data);
      now = bfd_time_now_nsec (vm, &vm_time);
      uword *session_index;
      switch (event_type)
	{
	case ~0:		/* no events => timeout */
	  /* nothing to do here */
	  break;
	case BFD_EVENT_RESCHEDULE:
	  BFD_DBG ("reschedule event");
	  bfd_lock (bm);
	  bm->bfd_process_wakeup_event_delay_nsec =
	    now - bm->bfd_process_wakeup_event_start_nsec;
	  bm->bfd_process_wakeup_events_in_flight--;
	  bfd_unlock (bm);
	  /* nothing to do here - reschedule is done automatically after
	   * each event or timeout */
	  break;
	case BFD_EVENT_NEW_SESSION:
	  vec_foreach (session_index, event_data)
	  {
	    bfd_lock (bm);
	    if (!pool_is_free_index (bm->sessions, *session_index))
	      {
		bfd_session_t *bs =
		  pool_elt_at_index (bm->sessions, *session_index);
		bfd_send_periodic (vm, rt, bm, bs, now);
		bfd_set_timer (bm, bs, now, 1);
	      }
	    else
	      {
		BFD_DBG ("Ignoring event for non-existent session index %u",
			 (u32) * session_index);
	      }
	    bfd_unlock (bm);
	  }
	  break;
	case BFD_EVENT_CONFIG_CHANGED:
	  vec_foreach (session_index, event_data)
	  {
	    bfd_lock (bm);
	    if (!pool_is_free_index (bm->sessions, *session_index))
	      {
		bfd_session_t *bs =
		  pool_elt_at_index (bm->sessions, *session_index);
		bfd_on_config_change (vm, rt, bm, bs, now);
	      }
	    else
	      {
		BFD_DBG ("Ignoring event for non-existent session index %u",
			 (u32) * session_index);
	      }
	    bfd_unlock (bm);
	  }
	  break;
	default:
	  vlib_log_err (bm->log_class, "BUG: event type 0x%wx", event_type);
	  break;
	}
      BFD_DBG ("tw_timer_expire_timers_vec(%p, %.04f);", &bm->wheel, vm_time);
      bfd_lock (bm);
      expired =
	TW (tw_timer_expire_timers_vec) (&bm->wheel, vm_time, expired);
      BFD_DBG ("Expired %d elements", vec_len (expired));
      u32 *p = NULL;
      vec_foreach (p, expired)
      {
	const u32 bs_idx = *p;
	if (!pool_is_free_index (bm->sessions, bs_idx))
	  {
	    bfd_session_t *bs = pool_elt_at_index (bm->sessions, bs_idx);
	    bs->tw_id = 0;	/* timer is gone because it expired */
	    bfd_on_timeout (vm, rt, bm, bs, now);
	    bfd_set_timer (bm, bs, now, 1);
	  }
      }
      bfd_unlock (bm);
      if (expired)
	{
	  _vec_len (expired) = 0;
	}
      if (event_data)
	{
	  _vec_len (event_data) = 0;
	}
    }

  return 0;
}

/*
 * bfd process node declaration
 */
/* *INDENT-OFF* */
VLIB_REGISTER_NODE (bfd_process_node, static) = {
  .function = bfd_process,
  .type = VLIB_NODE_TYPE_PROCESS,
  .name = "bfd-process",
  .n_next_nodes = 0,
  .next_nodes = {},
};
/* *INDENT-ON* */

static clib_error_t *
bfd_sw_interface_up_down (vnet_main_t * vnm, u32 sw_if_index, u32 flags)
{
  // bfd_main_t *bm = &bfd_main;
  // vnet_hw_interface_t *hi = vnet_get_sup_hw_interface (vnm, sw_if_index);
  if (!(flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP))
    {
      /* TODO */
    }
  return 0;
}

VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION (bfd_sw_interface_up_down);

static clib_error_t *
bfd_hw_interface_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags)
{
  // bfd_main_t *bm = &bfd_main;
  if (flags & VNET_HW_INTERFACE_FLAG_LINK_UP)
    {
      /* TODO */
    }
  return 0;
}

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
 */
static clib_error_t *
bfd_main_init (vlib_main_t * vm)
{
  vlib_thread_main_t *tm = &vlib_thread_main;
  u32 n_vlib_mains = tm->n_vlib_mains;
#if BFD_DEBUG
  setbuf (stdout, NULL);
#endif
  bfd_main_t *bm = &bfd_main;
  bm->random_seed = random_default_seed ();
  bm->vlib_main = vm;
  bm->vnet_main = vnet_get_main ();
  clib_memset (&bm->wheel, 0, sizeof (bm->wheel));
  bm->nsec_per_tw_tick = (f64) NSEC_PER_SEC / BFD_TW_TPS;
  bm->default_desired_min_tx_nsec =
    bfd_usec_to_nsec (BFD_DEFAULT_DESIRED_MIN_TX_USEC);
  bm->min_required_min_rx_while_echo_nsec =
    bfd_usec_to_nsec (BFD_REQUIRED_MIN_RX_USEC_WHILE_ECHO);
  BFD_DBG ("tw_timer_wheel_init(%p, %p, %.04f, %u)", &bm->wheel, NULL,
	   1.00 / BFD_TW_TPS, ~0);
  TW (tw_timer_wheel_init) (&bm->wheel, NULL, 1.00 / BFD_TW_TPS, ~0);
  bm->log_class = vlib_log_register_class ("bfd", 0);
  vlib_log_debug (bm->log_class, "initialized");
  bm->owner_thread_index = ~0;
  if (n_vlib_mains > 1)
    clib_spinlock_init (&bm->lock);
  return 0;
}

VLIB_INIT_FUNCTION (bfd_main_init);

bfd_session_t *
bfd_get_session (bfd_main_t * bm, bfd_transport_e t)
{
  bfd_session_t *result;

  bfd_lock (bm);

  pool_get (bm->sessions, result);
  clib_memset (result, 0, sizeof (*result));
  result->bs_idx = result - bm->sessions;
  result->transport = t;
  const unsigned limit = 1000;
  unsigned counter = 0;
  do
    {
      result->local_discr = random_u32 (&bm->random_seed);
      if (counter > limit)
	{
	  vlib_log_crit (bm->log_class,
			 "couldn't allocate unused session discriminator even "
			 "after %u tries!", limit);
	  pool_put (bm->sessions, result);
	  bfd_unlock (bm);
	  return NULL;
	}
      ++counter;
    }
  while (hash_get (bm->session_by_disc, result->local_discr));
  bfd_set_defaults (bm, result);
  hash_set (bm->session_by_disc, result->local_discr, result->bs_idx);
  bfd_unlock (bm);
  return result;
}

void
bfd_put_session (bfd_main_t * bm, bfd_session_t * bs)
{
  bfd_lock (bm);

  vlib_log_info (bm->log_class, "delete session: %U",
		 format_bfd_session_brief, bs);
  bfd_notify_listeners (bm, BFD_LISTEN_EVENT_DELETE, bs);
  if (bs->auth.curr_key)
    {
      --bs->auth.curr_key->use_count;
    }
  if (bs->auth.next_key)
    {
      --bs->auth.next_key->use_count;
    }
  hash_unset (bm->session_by_disc, bs->local_discr);
  pool_put (bm->sessions, bs);
  bfd_unlock (bm);
}

bfd_session_t *
bfd_find_session_by_idx (bfd_main_t * bm, uword bs_idx)
{
  bfd_lock_check (bm);
  if (!pool_is_free_index (bm->sessions, bs_idx))
    {
      return pool_elt_at_index (bm->sessions, bs_idx);
    }
  return NULL;
}

bfd_session_t *
bfd_find_session_by_disc (bfd_main_t * bm, u32 disc)
{
  bfd_lock_check (bm);
  uword *p = hash_get (bfd_main.session_by_disc, disc);
  if (p)
    {
      return pool_elt_at_index (bfd_main.sessions, *p);
    }
  return NULL;
}

/**
 * @brief verify bfd packet - common checks
 *
 * @param pkt
 *
 * @return 1 if bfd packet is valid
 */
int
bfd_verify_pkt_common (const bfd_pkt_t * pkt)
{
  if (1 != bfd_pkt_get_version (pkt))
    {
      BFD_ERR ("BFD verification failed - unexpected version: '%d'",
	       bfd_pkt_get_version (pkt));
      return 0;
    }
  if (pkt->head.length < sizeof (bfd_pkt_t) ||
      (bfd_pkt_get_auth_present (pkt) &&
       pkt->head.length < sizeof (bfd_pkt_with_common_auth_t)))
    {
      BFD_ERR ("BFD verification failed - unexpected length: '%d' (auth "
	       "present: %d)",
	       pkt->head.length, bfd_pkt_get_auth_present (pkt));
      return 0;
    }
  if (!pkt->head.detect_mult)
    {
      BFD_ERR ("BFD verification failed - unexpected detect-mult: '%d'",
	       pkt->head.detect_mult);
      return 0;
    }
  if (bfd_pkt_get_multipoint (pkt))
    {
      BFD_ERR ("BFD verification failed - unexpected multipoint: '%d'",
	       bfd_pkt_get_multipoint (pkt));
      return 0;
    }
  if (!pkt->my_disc)
    {
      BFD_ERR ("BFD verification failed - unexpected my-disc: '%d'",
	       pkt->my_disc);
      return 0;
    }
  if (!pkt->your_disc)
    {
      const u8 pkt_state = bfd_pkt_get_state (pkt);
      if (pkt_state != BFD_STATE_down && pkt_state != BFD_STATE_admin_down)
	{
	  BFD_ERR ("BFD verification failed - unexpected state: '%s' "
		   "(your-disc is zero)", bfd_state_string (pkt_state));
	  return 0;
	}
    }
  return 1;
}

static void
bfd_session_switch_auth_to_next (bfd_session_t * bs)
{
  BFD_DBG ("Switching authentication key from %U to %U for bs_idx=%u",
	   format_bfd_auth_key, bs->auth.curr_key, format_bfd_auth_key,
	   bs->auth.next_key, bs->bs_idx);
  bs->auth.is_delayed = 0;
  if (bs->auth.curr_key)
    {
      --bs->auth.curr_key->use_count;
    }
  bs->auth.curr_key = bs->auth.next_key;
  bs->auth.next_key = NULL;
  bs->auth.curr_bfd_key_id = bs->auth.next_bfd_key_id;
}

static int
bfd_auth_type_is_meticulous (bfd_auth_type_e auth_type)
{
  if (BFD_AUTH_TYPE_meticulous_keyed_md5 == auth_type ||
      BFD_AUTH_TYPE_meticulous_keyed_sha1 == auth_type)
    {
      return 1;
    }
  return 0;
}

static int
bfd_verify_pkt_auth_seq_num (vlib_main_t * vm, bfd_session_t * bs,
			     u32 received_seq_num, int is_meticulous)
{
  /*
   * RFC 5880 6.8.1:
   *
   * This variable MUST be set to zero after no packets have been
   * received on this session for at least twice the Detection Time.
   */
  u64 now = bfd_time_now_nsec (vm, NULL);
  if (now - bs->last_rx_nsec > bs->detection_time_nsec * 2)
    {
      BFD_DBG ("BFD peer unresponsive for %lu nsec, which is > 2 * "
	       "detection_time=%u nsec, resetting remote_seq_number_known "
	       "flag", now - bs->last_rx_nsec, bs->detection_time_nsec * 2);
      bs->auth.remote_seq_number_known = 0;
    }
  if (bs->auth.remote_seq_number_known)
    {
      /* remote sequence number is known, verify its validity */
      const u32 max_u32 = 0xffffffff;
      /* the calculation might wrap, account for the special case... */
      if (bs->auth.remote_seq_number > max_u32 - 3 * bs->local_detect_mult)
	{
	  /*
	   * special case
	   *
	   *        x                   y                   z
	   *  |----------+----------------------------+-----------|
	   *  0          ^                            ^ 0xffffffff
	   *             |        remote_seq_num------+
	   *             |
	   *             +-----(remote_seq_num + 3*detect_mult) % * 0xffffffff
	   *
	   *    x + y + z = 0xffffffff
	   *    x + z = 3 * detect_mult
	   */
	  const u32 z = max_u32 - bs->auth.remote_seq_number;
	  const u32 x = 3 * bs->local_detect_mult - z;
	  if (received_seq_num > x &&
	      received_seq_num < bs->auth.remote_seq_number + is_meticulous)
	    {
	      BFD_ERR
		("Recvd sequence number=%u out of ranges <0, %u>, <%u, %u>",
		 received_seq_num, x,
		 bs->auth.remote_seq_number + is_meticulous, max_u32);
	      return 0;
	    }
	}
      else
	{
	  /* regular case */
	  const u32 min = bs->auth.remote_seq_number + is_meticulous;
	  const u32 max =
	    bs->auth.remote_seq_number + 3 * bs->local_detect_mult;
	  if (received_seq_num < min || received_seq_num > max)
	    {
	      BFD_ERR ("Recvd sequence number=%u out of range <%u, %u>",
		       received_seq_num, min, max);
	      return 0;
	    }
	}
    }
  return 1;
}

static int
bfd_verify_pkt_auth_key_sha1 (const bfd_pkt_t * pkt, u32 pkt_size,
			      bfd_session_t * bs, u8 bfd_key_id,
			      bfd_auth_key_t * auth_key)
{
  ASSERT (auth_key->auth_type == BFD_AUTH_TYPE_keyed_sha1 ||
	  auth_key->auth_type == BFD_AUTH_TYPE_meticulous_keyed_sha1);

  u8 result[SHA_DIGEST_LENGTH];
  bfd_pkt_with_common_auth_t *with_common = (void *) pkt;
  if (pkt_size < sizeof (*with_common))
    {
      BFD_ERR ("Packet size too small to hold authentication common header");
      return 0;
    }
  if (with_common->common_auth.type != auth_key->auth_type)
    {
      BFD_ERR ("BFD auth type mismatch, packet auth=%d:%s doesn't match "
	       "in-use auth=%d:%s",
	       with_common->common_auth.type,
	       bfd_auth_type_str (with_common->common_auth.type),
	       auth_key->auth_type, bfd_auth_type_str (auth_key->auth_type));
      return 0;
    }
  bfd_pkt_with_sha1_auth_t *with_sha1 = (void *) pkt;
  if (pkt_size < sizeof (*with_sha1) ||
      with_sha1->sha1_auth.type_len.len < sizeof (with_sha1->sha1_auth))
    {
      BFD_ERR
	("BFD size mismatch, payload size=%u, expected=%u, auth_len=%u, "
	 "expected=%u", pkt_size, sizeof (*with_sha1),
	 with_sha1->sha1_auth.type_len.len, sizeof (with_sha1->sha1_auth));
      return 0;
    }
  if (with_sha1->sha1_auth.key_id != bfd_key_id)
    {
      BFD_ERR
	("BFD key ID mismatch, packet key ID=%u doesn't match key ID=%u%s",
	 with_sha1->sha1_auth.key_id, bfd_key_id,
	 bs->
	 auth.is_delayed ? " (but a delayed auth change is scheduled)" : "");
      return 0;
    }
  SHA_CTX ctx;
  if (!SHA1_Init (&ctx))
    {
      BFD_ERR ("SHA1_Init failed");
      return 0;
    }
  /* ignore last 20 bytes - use the actual key data instead pkt data */
  if (!SHA1_Update (&ctx, with_sha1,
		    sizeof (*with_sha1) - sizeof (with_sha1->sha1_auth.hash)))
    {
      BFD_ERR ("SHA1_Update failed");
      return 0;
    }
  if (!SHA1_Update (&ctx, auth_key->key, sizeof (auth_key->key)))
    {
      BFD_ERR ("SHA1_Update failed");
      return 0;
    }
  if (!SHA1_Final (result, &ctx))
    {
      BFD_ERR ("SHA1_Final failed");
      return 0;
    }
  if (0 == memcmp (result, with_sha1->sha1_auth.hash, SHA_DIGEST_LENGTH))
    {
      return 1;
    }
  BFD_ERR ("SHA1 hash: %U doesn't match the expected value: %U",
	   format_hex_bytes, with_sha1->sha1_auth.hash, SHA_DIGEST_LENGTH,
	   format_hex_bytes, result, SHA_DIGEST_LENGTH);
  return 0;
}

static int
bfd_verify_pkt_auth_key (vlib_main_t * vm, const bfd_pkt_t * pkt,
			 u32 pkt_size, bfd_session_t * bs, u8 bfd_key_id,
			 bfd_auth_key_t * auth_key)
{
  bfd_main_t *bm = &bfd_main;
  switch (auth_key->auth_type)
    {
    case BFD_AUTH_TYPE_reserved:
      vlib_log_err (bm->log_class,
		    "internal error, unexpected auth_type=%d:%s",
		    auth_key->auth_type,
		    bfd_auth_type_str (auth_key->auth_type));
      return 0;
    case BFD_AUTH_TYPE_simple_password:
      vlib_log_err (bm->log_class,
		    "internal error, not implemented, unexpected auth_type=%d:%s",
		    auth_key->auth_type,
		    bfd_auth_type_str (auth_key->auth_type));
      return 0;
    case BFD_AUTH_TYPE_keyed_md5:
      /* fallthrough */
    case BFD_AUTH_TYPE_meticulous_keyed_md5:
      vlib_log_err
	(bm->log_class,
	 "internal error, not implemented, unexpected auth_type=%d:%s",
	 auth_key->auth_type, bfd_auth_type_str (auth_key->auth_type));
      return 0;
    case BFD_AUTH_TYPE_keyed_sha1:
      /* fallthrough */
    case BFD_AUTH_TYPE_meticulous_keyed_sha1:
#if WITH_LIBSSL > 0
      do
	{
	  const u32 seq_num = clib_net_to_host_u32 (((bfd_pkt_with_sha1_auth_t
						      *) pkt)->
						    sha1_auth.seq_num);
	  return bfd_verify_pkt_auth_seq_num (vm, bs, seq_num,
					      bfd_auth_type_is_meticulous
					      (auth_key->auth_type))
	    && bfd_verify_pkt_auth_key_sha1 (pkt, pkt_size, bs, bfd_key_id,
					     auth_key);
	}
      while (0);
#else
      vlib_log_err
	(bm->log_class,
	 "internal error, attempt to use SHA1 without SSL support");
      return 0;
#endif
    }
  return 0;
}

/**
 * @brief verify bfd packet - authentication
 *
 * @param pkt
 *
 * @return 1 if bfd packet is valid
 */
int
bfd_verify_pkt_auth (vlib_main_t * vm, const bfd_pkt_t * pkt, u16 pkt_size,
		     bfd_session_t * bs)
{
  if (bfd_pkt_get_auth_present (pkt))
    {
      /* authentication present in packet */
      if (!bs->auth.curr_key)
	{
	  /* currently not using authentication - can we turn it on? */
	  if (bs->auth.is_delayed && bs->auth.next_key)
	    {
	      /* yes, switch is scheduled - make sure the auth is valid */
	      if (bfd_verify_pkt_auth_key (vm, pkt, pkt_size, bs,
					   bs->auth.next_bfd_key_id,
					   bs->auth.next_key))
		{
		  /* auth matches next key, do the switch, packet is valid */
		  bfd_session_switch_auth_to_next (bs);
		  return 1;
		}
	    }
	}
      else
	{
	  /* yes, using authentication, verify the key */
	  if (bfd_verify_pkt_auth_key (vm, pkt, pkt_size, bs,
				       bs->auth.curr_bfd_key_id,
				       bs->auth.curr_key))
	    {
	      /* verification passed, packet is valid */
	      return 1;
	    }
	  else
	    {
	      /* verification failed - but maybe we need to switch key */
	      if (bs->auth.is_delayed && bs->auth.next_key)
		{
		  /* delayed switch present, verify if that key works */
		  if (bfd_verify_pkt_auth_key (vm, pkt, pkt_size, bs,
					       bs->auth.next_bfd_key_id,
					       bs->auth.next_key))
		    {
		      /* auth matches next key, switch key, packet is valid */
		      bfd_session_switch_auth_to_next (bs);
		      return 1;
		    }
		}
	    }
	}
    }
  else
    {
      /* authentication in packet not present */
      if (pkt_size > sizeof (*pkt))
	{
	  BFD_ERR ("BFD verification failed - unexpected packet size '%d' "
		   "(auth not present)", pkt_size);
	  return 0;
	}
      if (bs->auth.curr_key)
	{
	  /* currently authenticating - could we turn it off? */
	  if (bs->auth.is_delayed && !bs->auth.next_key)
	    {
	      /* yes, delayed switch to NULL key is scheduled */
	      bfd_session_switch_auth_to_next (bs);
	      return 1;
	    }
	}
      else
	{
	  /* no auth in packet, no auth in use - packet is valid */
	  return 1;
	}
    }
  return 0;
}

void
bfd_consume_pkt (vlib_main_t * vm, bfd_main_t * bm, const bfd_pkt_t * pkt,
		 u32 bs_idx)
{
  bfd_lock_check (bm);

  bfd_session_t *bs = bfd_find_session_by_idx (bm, bs_idx);
  if (!bs || (pkt->your_disc && pkt->your_disc != bs->local_discr))
    {
      return;
    }
  BFD_DBG ("Scanning bfd packet, bs_idx=%d", bs->bs_idx);
  bs->remote_discr = pkt->my_disc;
  bs->remote_state = bfd_pkt_get_state (pkt);
  bs->remote_demand = bfd_pkt_get_demand (pkt);
  bs->remote_diag = bfd_pkt_get_diag_code (pkt);
  u64 now = bfd_time_now_nsec (vm, NULL);
  bs->last_rx_nsec = now;
  if (bfd_pkt_get_auth_present (pkt))
    {
      bfd_auth_type_e auth_type =
	((bfd_pkt_with_common_auth_t *) (pkt))->common_auth.type;
      switch (auth_type)
	{
	case BFD_AUTH_TYPE_reserved:
	  /* fallthrough */
	case BFD_AUTH_TYPE_simple_password:
	  /* fallthrough */
	case BFD_AUTH_TYPE_keyed_md5:
	  /* fallthrough */
	case BFD_AUTH_TYPE_meticulous_keyed_md5:
	  vlib_log_crit (bm->log_class,
			 "internal error, unexpected auth_type=%d:%s",
			 auth_type, bfd_auth_type_str (auth_type));
	  break;
	case BFD_AUTH_TYPE_keyed_sha1:
	  /* fallthrough */
	case BFD_AUTH_TYPE_meticulous_keyed_sha1:
	  do
	    {
	      bfd_pkt_with_sha1_auth_t *with_sha1 =
		(bfd_pkt_with_sha1_auth_t *) pkt;
	      bs->auth.remote_seq_number =
		clib_net_to_host_u32 (with_sha1->sha1_auth.seq_num);
	      bs->auth.remote_seq_number_known = 1;
	      BFD_DBG ("Received sequence number %u",
		       bs->auth.remote_seq_number);
	    }
	  while (0);
	}
    }
  bs->remote_desired_min_tx_nsec =
    bfd_usec_to_nsec (clib_net_to_host_u32 (pkt->des_min_tx));
  bs->remote_detect_mult = pkt->head.detect_mult;
  bfd_set_remote_required_min_rx (bm, bs, now,
				  clib_net_to_host_u32 (pkt->req_min_rx));
  bfd_set_remote_required_min_echo_rx (bm, bs, now,
				       clib_net_to_host_u32
				       (pkt->req_min_echo_rx));
  if (bfd_pkt_get_final (pkt))
    {
      if (BFD_POLL_IN_PROGRESS == bs->poll_state)
	{
	  BFD_DBG ("Poll sequence terminated, bs_idx=%u", bs->bs_idx);
	  bfd_set_poll_state (bs, BFD_POLL_NOT_NEEDED);
	  if (BFD_STATE_up == bs->local_state)
	    {
	      bfd_set_effective_required_min_rx (bm, bs,
						 clib_max (bs->echo *
							   bm->min_required_min_rx_while_echo_nsec,
							   bs->config_required_min_rx_nsec));
	    }
	}
      else if (BFD_POLL_IN_PROGRESS_AND_QUEUED == bs->poll_state)
	{
	  /*
	   * next poll sequence must be delayed by at least the round trip
	   * time, so calculate that here
	   */
	  BFD_DBG ("Next poll sequence can commence in " BFD_CLK_FMT,
		   BFD_CLK_PRN (now - bs->poll_state_start_or_timeout_nsec));
	  bs->poll_state_start_or_timeout_nsec =
	    now + (now - bs->poll_state_start_or_timeout_nsec);
	  BFD_DBG
	    ("Poll sequence terminated, but another is needed, bs_idx=%u",
	     bs->bs_idx);
	  bfd_set_poll_state (bs, BFD_POLL_NEEDED);
	}
    }
  bfd_calc_next_tx (bm, bs, now);
  bfd_set_timer (bm, bs, now, 0);
  if (BFD_STATE_admin_down == bs->local_state)
    {
      BFD_DBG ("Session is admin-down, ignoring packet, bs_idx=%u",
	       bs->bs_idx);
      return;
    }
  if (BFD_STATE_admin_down == bs->remote_state)
    {
      bfd_set_diag (bs, BFD_DIAG_CODE_neighbor_sig_down);
      bfd_set_state (vm, bm, bs, BFD_STATE_down, 0);
    }
  else if (BFD_STATE_down == bs->local_state)
    {
      if (BFD_STATE_down == bs->remote_state)
	{
	  bfd_set_diag (bs, BFD_DIAG_CODE_no_diag);
	  bfd_set_state (vm, bm, bs, BFD_STATE_init, 0);
	}
      else if (BFD_STATE_init == bs->remote_state)
	{
	  bfd_set_diag (bs, BFD_DIAG_CODE_no_diag);
	  bfd_set_state (vm, bm, bs, BFD_STATE_up, 0);
	}
    }
  else if (BFD_STATE_init == bs->local_state)
    {
      if (BFD_STATE_up == bs->remote_state ||
	  BFD_STATE_init == bs->remote_state)
	{
	  bfd_set_diag (bs, BFD_DIAG_CODE_no_diag);
	  bfd_set_state (vm, bm, bs, BFD_STATE_up, 0);
	}
    }
  else				/* BFD_STATE_up == bs->local_state */
    {
      if (BFD_STATE_down == bs->remote_state)
	{
	  bfd_set_diag (bs, BFD_DIAG_CODE_neighbor_sig_down);
	  bfd_set_state (vm, bm, bs, BFD_STATE_down, 0);
	}
    }
}

int
bfd_consume_echo_pkt (vlib_main_t * vm, bfd_main_t * bm, vlib_buffer_t * b)
{
  bfd_echo_pkt_t *pkt = NULL;
  if (b->current_length != sizeof (*pkt))
    {
      return 0;
    }
  pkt = vlib_buffer_get_current (b);
  bfd_session_t *bs = bfd_find_session_by_disc (bm, pkt->discriminator);
  if (!bs)
    {
      return 0;
    }
  BFD_DBG ("Scanning bfd echo packet, bs_idx=%d", bs->bs_idx);
  u64 checksum =
    bfd_calc_echo_checksum (bs->local_discr, pkt->expire_time_nsec,
			    bs->echo_secret);
  if (checksum != pkt->checksum)
    {
      BFD_DBG ("Invalid echo packet, checksum mismatch");
      return 1;
    }
  u64 now = bfd_time_now_nsec (vm, NULL);
  if (pkt->expire_time_nsec < now)
    {
      BFD_DBG ("Stale packet received, expire time %lu < now %lu",
	       pkt->expire_time_nsec, now);
    }
  else
    {
      bs->echo_last_rx_nsec = now;
    }
  return 1;
}

u8 *
format_bfd_session (u8 * s, va_list * args)
{
  const bfd_session_t *bs = va_arg (*args, bfd_session_t *);
  u32 indent = format_get_indent (s) + vlib_log_get_indent ();
  s = format (s, "bs_idx=%u local-state=%s remote-state=%s\n"
	      "%Ulocal-discriminator=%u remote-discriminator=%u\n"
	      "%Ulocal-diag=%s echo-active=%s\n"
	      "%Udesired-min-tx=%u required-min-rx=%u\n"
	      "%Urequired-min-echo-rx=%u detect-mult=%u\n"
	      "%Uremote-min-rx=%u remote-min-echo-rx=%u\n"
	      "%Uremote-demand=%s poll-state=%s\n"
	      "%Uauth: local-seq-num=%u remote-seq-num=%u\n"
	      "%U      is-delayed=%s\n"
	      "%U      curr-key=%U\n"
	      "%U      next-key=%U",
	      bs->bs_idx, bfd_state_string (bs->local_state),
	      bfd_state_string (bs->remote_state), format_white_space, indent,
	      bs->local_discr, bs->remote_discr, format_white_space, indent,
	      bfd_diag_code_string (bs->local_diag),
	      (bs->echo ? "yes" : "no"), format_white_space, indent,
	      bs->config_desired_min_tx_usec, bs->config_required_min_rx_usec,
	      format_white_space, indent, 1, bs->local_detect_mult,
	      format_white_space, indent, bs->remote_min_rx_usec,
	      bs->remote_min_echo_rx_usec, format_white_space, indent,
	      (bs->remote_demand ? "yes" : "no"),
	      bfd_poll_state_string (bs->poll_state), format_white_space,
	      indent, bs->auth.local_seq_number, bs->auth.remote_seq_number,
	      format_white_space, indent,
	      (bs->auth.is_delayed ? "yes" : "no"), format_white_space,
	      indent, format_bfd_auth_key, bs->auth.curr_key,
	      format_white_space, indent, format_bfd_auth_key,
	      bs->auth.next_key);
  return s;
}

u8 *
format_bfd_session_brief (u8 * s, va_list * args)
{
  const bfd_session_t *bs = va_arg (*args, bfd_session_t *);
  s =
    format (s, "bs_idx=%u local-state=%s remote-state=%s", bs->bs_idx,
	    bfd_state_string (bs->local_state),
	    bfd_state_string (bs->remote_state));
  return s;
}

unsigned
bfd_auth_type_supported (bfd_auth_type_e auth_type)
{
  if (auth_type == BFD_AUTH_TYPE_keyed_sha1 ||
      auth_type == BFD_AUTH_TYPE_meticulous_keyed_sha1)
    {
      return 1;
    }
  return 0;
}

vnet_api_error_t
bfd_auth_activate (bfd_session_t * bs, u32 conf_key_id,
		   u8 bfd_key_id, u8 is_delayed)
{
  bfd_main_t *bm = &bfd_main;
  const uword *key_idx_p =
    hash_get (bm->auth_key_by_conf_key_id, conf_key_id);
  if (!key_idx_p)
    {
      vlib_log_err (bm->log_class,
		    "authentication key with config ID %u doesn't exist)",
		    conf_key_id);
      return VNET_API_ERROR_BFD_ENOENT;
    }
  const uword key_idx = *key_idx_p;
  bfd_auth_key_t *key = pool_elt_at_index (bm->auth_keys, key_idx);
  if (is_delayed)
    {
      if (bs->auth.next_key == key)
	{
	  /* already using this key, no changes required */
	  return 0;
	}
      bs->auth.next_key = key;
      bs->auth.next_bfd_key_id = bfd_key_id;
      bs->auth.is_delayed = 1;
    }
  else
    {
      if (bs->auth.curr_key == key)
	{
	  /* already using this key, no changes required */
	  return 0;
	}
      if (bs->auth.curr_key)
	{
	  --bs->auth.curr_key->use_count;
	}
      bs->auth.curr_key = key;
      bs->auth.curr_bfd_key_id = bfd_key_id;
      bs->auth.is_delayed = 0;
    }
  ++key->use_count;
  BFD_DBG ("\nSession auth modified: %U", format_bfd_session, bs);
  vlib_log_info (bm->log_class, "session auth modified: %U",
		 format_bfd_session_brief, bs);
  return 0;
}

vnet_api_error_t
bfd_auth_deactivate (bfd_session_t * bs, u8 is_delayed)
{
  bfd_main_t *bm = &bfd_main;
#if WITH_LIBSSL > 0
  if (!is_delayed)
    {
      /* not delayed - deactivate the current key right now */
      if (bs->auth.curr_key)
	{
	  --bs->auth.curr_key->use_count;
	  bs->auth.curr_key = NULL;
	}
      bs->auth.is_delayed = 0;
    }
  else
    {
      /* delayed - mark as so */
      bs->auth.is_delayed = 1;
    }
  /*
   * clear the next key unconditionally - either the auth change is not delayed
   * in which case the caller expects the session to not use authentication
   * from this point forward, or it is delayed, in which case the next_key
   * needs to be set to NULL to make it so in the future
   */
  if (bs->auth.next_key)
    {
      --bs->auth.next_key->use_count;
      bs->auth.next_key = NULL;
    }
  BFD_DBG ("\nSession auth modified: %U", format_bfd_session, bs);
  vlib_log_info (bm->log_class, "session auth modified: %U",
		 format_bfd_session_brief, bs);
  return 0;
#else
  vlib_log_err (bm->log_class,
		"SSL missing, cannot deactivate BFD authentication");
  return VNET_API_ERROR_BFD_NOTSUPP;
#endif
}

vnet_api_error_t
bfd_session_set_params (bfd_main_t * bm, bfd_session_t * bs,
			u32 desired_min_tx_usec,
			u32 required_min_rx_usec, u8 detect_mult)
{
  if (bs->local_detect_mult != detect_mult ||
      bs->config_desired_min_tx_usec != desired_min_tx_usec ||
      bs->config_required_min_rx_usec != required_min_rx_usec)
    {
      BFD_DBG ("\nChanging session params: %U", format_bfd_session, bs);
      switch (bs->poll_state)
	{
	case BFD_POLL_NOT_NEEDED:
	  if (BFD_STATE_up == bs->local_state ||
	      BFD_STATE_init == bs->local_state)
	    {
	      /* poll sequence is not needed for detect multiplier change */
	      if (bs->config_desired_min_tx_usec != desired_min_tx_usec ||
		  bs->config_required_min_rx_usec != required_min_rx_usec)
		{
		  bfd_set_poll_state (bs, BFD_POLL_NEEDED);
		}
	    }
	  break;
	case BFD_POLL_NEEDED:
	case BFD_POLL_IN_PROGRESS_AND_QUEUED:
	  /*
	   * nothing to do - will be handled in the future poll which is
	   * already scheduled for execution
	   */
	  break;
	case BFD_POLL_IN_PROGRESS:
	  /* poll sequence is not needed for detect multiplier change */
	  if (bs->config_desired_min_tx_usec != desired_min_tx_usec ||
	      bs->config_required_min_rx_usec != required_min_rx_usec)
	    {
	      BFD_DBG ("Poll in progress, queueing extra poll, bs_idx=%u",
		       bs->bs_idx);
	      bfd_set_poll_state (bs, BFD_POLL_IN_PROGRESS_AND_QUEUED);
	    }
	}

      bs->local_detect_mult = detect_mult;
      bs->config_desired_min_tx_usec = desired_min_tx_usec;
      bs->config_desired_min_tx_nsec = bfd_usec_to_nsec (desired_min_tx_usec);
      bs->config_required_min_rx_usec = required_min_rx_usec;
      bs->config_required_min_rx_nsec =
	bfd_usec_to_nsec (required_min_rx_usec);
      BFD_DBG ("\nChanged session params: %U", format_bfd_session, bs);

      vlib_log_info (bm->log_class, "changed session params: %U",
		     format_bfd_session_brief, bs);
      vlib_process_signal_event (bm->vlib_main, bm->bfd_process_node_index,
				 BFD_EVENT_CONFIG_CHANGED, bs->bs_idx);
    }
  else
    {
      BFD_DBG ("Ignore parameter change - no change, bs_idx=%u", bs->bs_idx);
    }
  return 0;
}

vnet_api_error_t
bfd_auth_set_key (u32 conf_key_id, u8 auth_type, u8 key_len,
		  const u8 * key_data)
{
  bfd_main_t *bm = &bfd_main;
#if WITH_LIBSSL > 0
  bfd_auth_key_t *auth_key = NULL;
  if (!key_len || key_len > bfd_max_key_len_for_auth_type (auth_type))
    {
      vlib_log_err (bm->log_class,
		    "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_key_len_for_auth_type (auth_type));
      return VNET_API_ERROR_INVALID_VALUE;
    }
  if (!bfd_auth_type_supported (auth_type))
    {
      vlib_log_err (bm->log_class, "unsupported auth type=%d:%s", auth_type,
		    bfd_auth_type_str (auth_type));
      return VNET_API_ERROR_BFD_NOTSUPP;
    }
  uword *key_idx_p = hash_get (bm->auth_key_by_conf_key_id, conf_key_id);
  if (key_idx_p)
    {
      /* modifying existing key - must not be used */
      const uword key_idx = *key_idx_p;
      auth_key = pool_elt_at_index (bm->auth_keys, key_idx);
      if (auth_key->use_count > 0)
	{
	  vlib_log_err (bm->log_class,
			"authentication key with conf ID %u in use by %u BFD "
			"session(s) - cannot modify", conf_key_id,
			auth_key->use_count);
	  return VNET_API_ERROR_BFD_EINUSE;
	}
    }
  else
    {
      /* adding new key */
      pool_get (bm->auth_keys, auth_key);
      auth_key->conf_key_id = conf_key_id;
      hash_set (bm->auth_key_by_conf_key_id, conf_key_id,
		auth_key - bm->auth_keys);
    }
  auth_key->auth_type = auth_type;
  clib_memset (auth_key->key, 0, sizeof (auth_key->key));
  clib_memcpy (auth_key->key, key_data, key_len);
  return 0;
#else
  vlib_log_err (bm->log_class,
		"SSL missing, cannot manipulate authentication keys");
  return VNET_API_ERROR_BFD_NOTSUPP;
#endif
}

vnet_api_error_t
bfd_auth_del_key (u32 conf_key_id)
{
#if WITH_LIBSSL > 0
  bfd_auth_key_t *auth_key = NULL;
  bfd_main_t *bm = &bfd_main;
  uword *key_idx_p = hash_get (bm->auth_key_by_conf_key_id, conf_key_id);
  if (key_idx_p)
    {
      /* deleting existing key - must not be used */
      const uword key_idx = *key_idx_p;
      auth_key = pool_elt_at_index (bm->auth_keys, key_idx);
      if (auth_key->use_count > 0)
	{
	  vlib_log_err (bm->log_class,
			"authentication key with conf ID %u in use by %u BFD "
			"session(s) - cannot delete", conf_key_id,
			auth_key->use_count);
	  return VNET_API_ERROR_BFD_EINUSE;
	}
      hash_unset (bm->auth_key_by_conf_key_id, conf_key_id);
      clib_memset (auth_key, 0, sizeof (*auth_key));
      pool_put (bm->auth_keys, auth_key);
    }
  else
    {
      /* no such key */
      vlib_log_err (bm->log_class,
		    "authentication key with conf ID %u does not exist",
		    conf_key_id);
      return VNET_API_ERROR_BFD_ENOENT;
    }
  return 0;
#else
  vlib_log_err (bm->log_class,
		"SSL missing, cannot manipulate authentication keys");
  return VNET_API_ERROR_BFD_NOTSUPP;
#endif
}

bfd_main_t bfd_main;

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
