*/
static void
-bfd_request_notify(struct bfd_request *req, u8 state, u8 diag)
+bfd_request_notify(struct bfd_request *req, u8 state, u8 remote, u8 diag)
{
u8 old_state = req->state;
req->state = state;
req->diag = diag;
req->old_state = old_state;
- req->down = (old_state == BFD_STATE_UP) && (state == BFD_STATE_DOWN);
+ req->down = (old_state == BFD_STATE_UP) && (state == BFD_STATE_DOWN) && (remote != BFD_STATE_ADMIN_DOWN);
if (req->hook)
req->hook(req);
uint ifindex = req->iface ? req->iface->index : 0;
struct bfd_session *s = bfd_find_session_by_addr(p, req->addr, ifindex);
- u8 state, diag;
+ u8 loc_state, rem_state, diag;
if (!s)
s = bfd_add_session(p, req->addr, req->local, req->iface, &req->opts);
req->session = s;
bfd_lock_sessions(p);
- state = s->loc_state;
+ loc_state = s->loc_state;
+ rem_state = s->rem_state;
diag = s->loc_diag;
bfd_unlock_sessions(p);
- bfd_request_notify(req, state, diag);
+ bfd_request_notify(req, loc_state, rem_state, diag);
return 1;
}
rem_node(&req->n);
add_tail(&bfd_wait_list, &req->n);
req->session = NULL;
- bfd_request_notify(req, BFD_STATE_ADMIN_DOWN, 0);
+ bfd_request_notify(req, BFD_STATE_ADMIN_DOWN, BFD_STATE_ADMIN_DOWN, 0);
}
static void
struct bfd_proto *p = sk->data;
struct bfd_session *s;
list tmp_list;
- u8 state, diag;
+ u8 loc_state, rem_state, diag;
node *n, *nn;
pipe_drain(sk->fd);
{
bfd_lock_sessions(p);
rem_node(&s->n);
- state = s->loc_state;
+ loc_state = s->loc_state;
+ rem_state = s->rem_state;
diag = s->loc_diag;
bfd_unlock_sessions(p);
s->notify_running = 1;
WALK_LIST_DELSAFE(n, nn, s->request_list)
- bfd_request_notify(SKIP_BACK(struct bfd_request, n, n), state, diag);
+ bfd_request_notify(SKIP_BACK(struct bfd_request, n, n), loc_state, rem_state, diag);
s->notify_running = 0;
/* Remove the session if all requests were removed in notify hooks */