]> git.puffer.fish Git - mirror/frr.git/commitdiff
[bgpd] Fix bug where FSM can stay hung forever in Idle/Clrng
authorPaul Jakma <paul.jakma@sun.com>
Thu, 4 May 2006 08:08:15 +0000 (08:08 +0000)
committerPaul Jakma <paul.jakma@sun.com>
Thu, 4 May 2006 08:08:15 +0000 (08:08 +0000)
2006-05-04 Paul Jakma <paul.jakma@sun.com>

* bgp_route.c: (general) Fix logical bug in clearing, noted
  by Chris Caputo in [quagga-users 6728] - clearing depended on
  at least one route being added to workqueue, in order for
  workqueue completion function to restart FSM. However, if no
  routes are cleared, then the completion function never is
  called, it needs to be called manually if the workqueue
  didn't get scheduled.
  Finally, clearing is per-peer-session, not per AFI/SAFI, so
  the FSM synchronisation should be in bgp_clear_route_table.
  (bgp_clear_route_table) Wrong place for FSM/clearing
  synchronisation, move to..
  (bgp_clear_route) FSM/clearing synchronisation should be
  here.
  If no routes were cleared, no workqueue scheduled, call
  the completion func to ensure FSM kicks off again.

bgpd/ChangeLog
bgpd/bgp_route.c

index a0ba520c7a9413d6764b17acbb4092443b3a00d3..5599801e681d444251bcc9f58dee81df5c898109 100644 (file)
@@ -7,6 +7,21 @@
        * bgp_packet.c: (bgp_{update,withdraw}_packet) Enable some
          VPNv4 code which inexplicably was ifdef'd out. comments from
          a tester on IRC suggest this fixes bug #210.
+       * bgp_route.c: (general) Fix logical bug in clearing, noted
+         by Chris Caputo in [quagga-users 6728] - clearing depended on
+         at least one route being added to workqueue, in order for
+         workqueue completion function to restart FSM. However, if no
+         routes are cleared, then the completion function never is
+         called, it needs to be called manually if the workqueue
+         didn't get scheduled. 
+         Finally, clearing is per-peer-session, not per AFI/SAFI, so
+         the FSM synchronisation should be in bgp_clear_route_table.
+         (bgp_clear_route_table) Wrong place for FSM/clearing
+         synchronisation, move to..
+         (bgp_clear_route) FSM/clearing synchronisation should be
+         here.
+         If no routes were cleared, no workqueue scheduled, call
+         the completion func to ensure FSM kicks off again.
 
 2006-03-30 Paul Jakma <paul.jakma@sun.com>
 
index b49bea9880b6644a63ae1f8767b8c134e347a0c1..10c88697921aedbe5af6e545aba03a8c139e8144 100644 (file)
@@ -2555,6 +2555,25 @@ bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi,
   /* If still no table => afi/safi isn't configured at all or smth. */
   if (! table)
     return;
+  
+  for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
+    {
+      if (rn->info == NULL)
+        continue;
+      
+      bgp_lock_node (rn); /* unlocked: bgp_clear_node_queue_del */
+      work_queue_add (peer->clear_node_queue, rn);
+    }
+  return;
+}
+
+void
+bgp_clear_route (struct peer *peer, afi_t afi, safi_t safi)
+{
+  struct bgp_node *rn;
+  struct bgp_table *table;
+  struct peer *rsclient;
+  struct listnode *node, *nnode;
 
   if (peer->clear_node_queue == NULL)
     bgp_clear_node_queue_init (peer);
@@ -2576,25 +2595,6 @@ bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi,
       peer_lock (peer); /* bgp_clear_node_complete */
     }
   
-  for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
-    {
-      if (rn->info == NULL)
-        continue;
-      
-      bgp_lock_node (rn); /* unlocked: bgp_clear_node_queue_del */
-      work_queue_add (peer->clear_node_queue, rn);
-    }
-  return;
-}
-
-void
-bgp_clear_route (struct peer *peer, afi_t afi, safi_t safi)
-{
-  struct bgp_node *rn;
-  struct bgp_table *table;
-  struct peer *rsclient;
-  struct listnode *node, *nnode;
-
   if (safi != SAFI_MPLS_VPN)
     bgp_clear_route_table (peer, afi, safi, NULL, NULL);
   else
@@ -2608,6 +2608,12 @@ bgp_clear_route (struct peer *peer, afi_t afi, safi_t safi)
       if (CHECK_FLAG(rsclient->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
         bgp_clear_route_table (peer, afi, safi, NULL, rsclient);
     }
+  
+  /* If no routes were cleared, nothing was added to workqueue, run the
+   * completion function now.
+   */
+  if (!peer->clear_node_queue->thread)
+    bgp_clear_node_complete (peer->clear_node_queue);
 }
   
 void