* the needs of BFD sessions. When a new session is created, it requests a
* proper BFD interface by function bfd_get_iface(), which either finds an
* existing one in &iface_list (from &bfd_proto) or allocates a new one. When a
- * session is removed, an associated iface is dicharged by bfd_free_iface().
+ * session is removed, an associated iface is discharged by bfd_free_iface().
*
* BFD requests are the external API for the other protocols. When a protocol
* wants a BFD session, it calls bfd_request_session(), which creates a
* configuration (like static routes in the static protocol). BFD neighbors are
* handled by BFD protocol like it is a BFD client -- when a BFD neighbor is
* ready, the protocol just creates a BFD request like any other protocol.
- *
+ *
* The protocol uses a new generic event loop (structure &birdloop) from |io.c|,
* which supports sockets, timers and events like the main loop. Timers
* (structure &timer2) are new microsecond based timers, while sockets and
* BFD sessions
*/
-static void
+static void
bfd_session_update_state(struct bfd_session *s, uint state, uint diag)
{
struct bfd_proto *p = s->ifa->bfd;
- uint old_state = s->loc_state;
+ uint old_state = s->loc_state;
int notify;
if (state == old_state)
if (s->passive && (s->rem_id == 0))
goto stop;
- if (s->rem_demand_mode &&
- !s->poll_active &&
+ if (s->rem_demand_mode &&
+ !s->poll_active &&
(s->loc_state == BFD_STATE_UP) &&
(s->rem_state == BFD_STATE_UP))
goto stop;
bfd_send_ctl(s->ifa->bfd, s, 1);
}
-static void
+static void
bfd_session_timeout(struct bfd_session *s)
{
struct bfd_proto *p = s->ifa->bfd;
if (val == s->req_min_rx_new)
return;
- s->req_min_rx_new = val;
+ s->req_min_rx_new = val;
/* Postpone timer update if req_min_rx_int decreases and the session is up */
if ((s->loc_state != BFD_STATE_UP) || (val > s->req_min_rx_int))
if (!ifa || --ifa->uc)
return;
+ if (ifa->sk)
+ {
+ sk_stop(ifa->sk);
+ rfree(ifa->sk);
+ }
+
rem_node(&ifa->n);
- sk_stop(ifa->sk);
- rfree(ifa->sk);
mb_free(ifa);
}
diag = s->loc_diag;
bfd_unlock_sessions(p);
- /* FIXME: convert to btime and move to bfd_session_update_state() */
+ /* FIXME: convert to btime and move to bfd_session_update_state() */
s->last_state_change = now;
s->notify_running = 1;
/* FIXME: this is thread-unsafe, but perhaps harmless */
state = s->loc_state;
diag = s->loc_diag;
- ifname = (s->ifa && s->ifa->sk->iface) ? s->ifa->sk->iface->name : "---";
+ ifname = (s->ifa && s->ifa->iface) ? s->ifa->iface->name : "---";
tx_int = s->last_tx ? (MAX(s->des_min_tx_int, s->rem_min_rx_int) TO_MS) : 0;
timeout = (MAX(s->req_min_rx_int, s->rem_min_tx_int) TO_MS) * s->rem_detect_mult;
bfd_send_ctl(struct bfd_proto *p, struct bfd_session *s, int final)
{
sock *sk = s->ifa->sk;
- struct bfd_ctl_packet *pkt = (struct bfd_ctl_packet *) sk->tbuf;
+ struct bfd_ctl_packet *pkt;
char fb[8];
+ if (!sk)
+ return;
+
+ pkt = (struct bfd_ctl_packet *) sk->tbuf;
pkt->vdiag = bfd_pack_vdiag(1, s->loc_diag);
pkt->flags = bfd_pack_flags(s->loc_state, 0);
pkt->detect_mult = s->detect_mult;
u8 ps = bfd_pkt_get_state(pkt);
if (ps > BFD_STATE_DOWN)
DROP("invalid init state", ps);
-
+
s = bfd_find_session_by_addr(p, sk->faddr);
/* FIXME: better session matching and message */