Fixes stuck connection during BGP session shutdown.

If TX buffers were full during BGP session shutdown
then a protocol waited indefinitely to be able to
send notification packet to close the session.
This commit is contained in:
Ondrej Zajicek 2013-07-13 01:39:41 +02:00
parent 354496ace8
commit 48b15ef10f

View file

@ -384,10 +384,12 @@ bgp_conn_enter_close_state(struct bgp_conn *conn)
int os = conn->state; int os = conn->state;
bgp_conn_set_state(conn, BS_CLOSE); bgp_conn_set_state(conn, BS_CLOSE);
tm_stop(conn->hold_timer);
tm_stop(conn->keepalive_timer); tm_stop(conn->keepalive_timer);
conn->sk->rx_hook = NULL; conn->sk->rx_hook = NULL;
/* Timeout for CLOSE state, if we cannot send notification soon then we just hangup */
bgp_start_timer(conn->hold_timer, 10);
if (os == BS_ESTABLISHED) if (os == BS_ESTABLISHED)
bgp_conn_leave_established_state(p); bgp_conn_leave_established_state(p);
} }
@ -478,9 +480,18 @@ static void
bgp_hold_timeout(timer *t) bgp_hold_timeout(timer *t)
{ {
struct bgp_conn *conn = t->data; struct bgp_conn *conn = t->data;
struct bgp_proto *p = conn->bgp;
DBG("BGP: Hold timeout\n"); DBG("BGP: Hold timeout\n");
/* We are already closing the connection - just do hangup */
if (conn->state == BS_CLOSE)
{
BGP_TRACE(D_EVENTS, "Connection stalled");
bgp_conn_enter_idle_state(conn);
return;
}
/* If there is something in input queue, we are probably congested /* If there is something in input queue, we are probably congested
and perhaps just not processed BGP packets in time. */ and perhaps just not processed BGP packets in time. */