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 |