diff options
Diffstat (limited to 'bgpd')
| -rw-r--r-- | bgpd/ChangeLog | 15 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 44 | 
2 files changed, 40 insertions, 19 deletions
| diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog index a0ba520c..5599801e 100644 --- a/bgpd/ChangeLog +++ b/bgpd/ChangeLog @@ -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> diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index b49bea98..10c88697 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -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 | 
