BFD_INPUT_N_NEXT,
} bfd_input_next_t;
-static void bfd_on_state_change (bfd_main_t * bm, bfd_session_t * bs,
- u64 now);
+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)
}
static void
-bfd_set_state (bfd_main_t * bm, bfd_session_t * bs, bfd_state_e new_state)
+bfd_set_state (bfd_main_t * bm, bfd_session_t * bs,
+ bfd_state_e new_state, int handling_wakeup)
{
if (bs->local_state != new_state)
{
bfd_state_string (bs->local_state),
bfd_state_string (new_state));
bs->local_state = new_state;
- bfd_on_state_change (bm, bs, clib_cpu_time_now ());
+ bfd_on_state_change (bm, bs, clib_cpu_time_now (), handling_wakeup);
}
}
}
static void
-bfd_set_timer (bfd_main_t * bm, bfd_session_t * bs, u64 now)
+bfd_set_timer (bfd_main_t * bm, bfd_session_t * bs, u64 now,
+ int handling_wakeup)
{
u64 next = 0;
u64 rx_timeout = 0;
(i64) (bs->wheel_time_clocks - clib_cpu_time_now ()) /
bm->cpu_cps, bs->bs_idx);
timing_wheel_insert (&bm->wheel, bs->wheel_time_clocks, bs->bs_idx);
+ if (!handling_wakeup)
+ {
+ vlib_process_signal_event (bm->vlib_main,
+ bm->bfd_process_node_index,
+ BFD_EVENT_RESCHEDULE, bs->bs_idx);
+ }
}
}
static void
bfd_set_desired_min_tx (bfd_main_t * bm, bfd_session_t * bs, u64 now,
- u32 desired_min_tx_us)
+ u32 desired_min_tx_us, int handling_wakeup)
{
bs->desired_min_tx_us = desired_min_tx_us;
bs->desired_min_tx_clocks = bfd_us_to_clocks (bm, bs->desired_min_tx_us);
bfd_recalc_detection_time (bm, bs);
bfd_recalc_tx_interval (bm, bs);
bfd_calc_next_tx (bm, bs, now);
- bfd_set_timer (bm, bs, now);
+ bfd_set_timer (bm, bs, now, handling_wakeup);
}
void
bfd_session_t *bs = pool_elt_at_index (bm->sessions, bs_idx);
if (admin_up_down)
{
- bfd_set_state (bm, bs, BFD_STATE_down);
+ bfd_set_state (bm, bs, BFD_STATE_down, 0);
}
else
{
bfd_set_diag (bs, BFD_DIAG_CODE_neighbor_sig_down);
- bfd_set_state (bm, bs, BFD_STATE_admin_down);
+ bfd_set_state (bm, bs, BFD_STATE_admin_down, 0);
}
return 0;
}
}
static void
-bfd_on_state_change (bfd_main_t * bm, bfd_session_t * bs, u64 now)
+bfd_on_state_change (bfd_main_t * bm, bfd_session_t * bs, u64 now,
+ int handling_wakeup)
{
BFD_DBG ("State changed: %U", format_bfd_session, bs);
bfd_event (bm, bs);
case BFD_STATE_admin_down:
bfd_set_desired_min_tx (bm, bs, now,
clib_max (bs->config_desired_min_tx_us,
- BFD_DEFAULT_DESIRED_MIN_TX_US));
+ BFD_DEFAULT_DESIRED_MIN_TX_US),
+ handling_wakeup);
break;
case BFD_STATE_down:
bfd_set_desired_min_tx (bm, bs, now,
clib_max (bs->config_desired_min_tx_us,
- BFD_DEFAULT_DESIRED_MIN_TX_US));
+ BFD_DEFAULT_DESIRED_MIN_TX_US),
+ handling_wakeup);
break;
case BFD_STATE_init:
bfd_set_desired_min_tx (bm, bs, now,
clib_max (bs->config_desired_min_tx_us,
- BFD_DEFAULT_DESIRED_MIN_TX_US));
+ BFD_DEFAULT_DESIRED_MIN_TX_US),
+ handling_wakeup);
break;
case BFD_STATE_up:
- bfd_set_desired_min_tx (bm, bs, now, bs->config_desired_min_tx_us);
+ bfd_set_desired_min_tx (bm, bs, now, bs->config_desired_min_tx_us,
+ handling_wakeup);
break;
}
}
static void
bfd_send_periodic (vlib_main_t * vm, vlib_node_runtime_t * rt,
- bfd_main_t * bm, bfd_session_t * bs, u64 now)
+ bfd_main_t * bm, bfd_session_t * bs, u64 now,
+ int handling_wakeup)
{
if (!bs->remote_min_rx_us)
{
{
BFD_DBG ("No need to send control frame now");
}
- bfd_set_timer (bm, bs, now);
+ bfd_set_timer (bm, bs, now, handling_wakeup);
}
void
}
static void
-bfd_check_rx_timeout (bfd_main_t * bm, bfd_session_t * bs, u64 now)
+bfd_check_rx_timeout (bfd_main_t * bm, bfd_session_t * bs, u64 now,
+ int handling_wakeup)
{
if (bs->last_rx_clocks + bs->detection_time_clocks < now)
{
BFD_DBG ("Rx timeout, session goes down");
bfd_set_diag (bs, BFD_DIAG_CODE_det_time_exp);
- bfd_set_state (bm, bs, BFD_STATE_down);
+ bfd_set_state (bm, bs, BFD_STATE_down, handling_wakeup);
}
}
abort ();
break;
case BFD_STATE_down:
- bfd_send_periodic (vm, rt, bm, bs, now);
+ bfd_send_periodic (vm, rt, bm, bs, now, 1);
break;
case BFD_STATE_init:
BFD_ERR ("Unexpected timeout when in %s state",
abort ();
break;
case BFD_STATE_up:
- bfd_check_rx_timeout (bm, bs, now);
- bfd_send_periodic (vm, rt, bm, bs, now);
+ bfd_check_rx_timeout (bm, bs, now, 1);
+ bfd_send_periodic (vm, rt, bm, bs, now, 1);
break;
}
}
{
bfd_session_t *bs =
pool_elt_at_index (bm->sessions, *event_data);
- bfd_send_periodic (vm, rt, bm, bs, now);
+ bfd_send_periodic (vm, rt, bm, bs, now, 1);
}
while (0);
break;
{
bfd_session_t *result;
pool_get (bm->sessions, result);
+ memset (result, 0, sizeof (*result));
result->bs_idx = result - bm->sessions;
result->transport = t;
result->local_discr = random_u32 (&bm->random_seed);
if (BFD_STATE_admin_down == bs->remote_state)
{
bfd_set_diag (bs, BFD_DIAG_CODE_neighbor_sig_down);
- bfd_set_state (bm, bs, BFD_STATE_down);
+ bfd_set_state (bm, bs, BFD_STATE_down, 0);
}
else if (BFD_STATE_down == bs->local_state)
{
if (BFD_STATE_down == bs->remote_state)
{
- bfd_set_state (bm, bs, BFD_STATE_init);
+ bfd_set_state (bm, bs, BFD_STATE_init, 0);
}
else if (BFD_STATE_init == bs->remote_state)
{
- bfd_set_state (bm, bs, BFD_STATE_up);
+ bfd_set_state (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_state (bm, bs, BFD_STATE_up);
+ bfd_set_state (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 (bm, bs, BFD_STATE_down);
+ bfd_set_state (bm, bs, BFD_STATE_down, 0);
}
}
}