]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Fixes stuck connection during BGP session shutdown.
authorOndrej Zajicek <santiago@crfreenet.org>
Fri, 12 Jul 2013 23:39:41 +0000 (01:39 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Fri, 12 Jul 2013 23:39:41 +0000 (01:39 +0200)
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.

proto/bgp/bgp.c

index b1594b9296994d85abb4fd81e56c7de6f632b2bb..3215345209abbc1c0fcdf185328b1880f11658de 100644 (file)
@@ -384,10 +384,12 @@ bgp_conn_enter_close_state(struct bgp_conn *conn)
   int os = conn->state;
 
   bgp_conn_set_state(conn, BS_CLOSE);
-  tm_stop(conn->hold_timer);
   tm_stop(conn->keepalive_timer);
   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)
     bgp_conn_leave_established_state(p);
 }
@@ -478,9 +480,18 @@ static void
 bgp_hold_timeout(timer *t)
 {
   struct bgp_conn *conn = t->data;
+  struct bgp_proto *p = conn->bgp;
 
   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
      and perhaps just not processed BGP packets in time. */