Index: ChangeLog =================================================================== RCS file: /var/cvsroot/quagga/bgpd/ChangeLog,v retrieving revision 1.67 diff -u -p -r1.67 ChangeLog --- ChangeLog 3 Aug 2005 17:23:20 -0000 1.67 +++ ChangeLog 16 Aug 2005 17:24:40 -0000 @@ -1,3 +1,43 @@ +2005-08-16 Paul Jakma + + * bgp_route.h: (struct bgp_info) add a new flag, BGP_INFO_REMOVED. + BGP_INFO_VALID is already overloaded, don't care to do same thing + to STALE or HISTORY. + (bgp_process) add a bgp_info argument, so that bgp_process can + lock it and ensure it stays in the RIB until the bgp_process + queue-runner runs - otherwise withdrawals of routes will never + be communicated to zebra (cause it disappears from RIB before + we do best-path selection). + * bgpd.h: (BGP_INFO_HOLDDOWN) Add INFO_REMOVED to the macro, as a + route which should generally be ignored. + * bgp_route.c: (bgp_info_delete) Just set the REMOVE flag, rather + than doing actual work, so that bgp_process (called directly, + or indirectly via the scanner) can catch withdrawn routes. + (bgp_info_remove) Actually remove the route, what bgp_info_delete + used to do, only for use by bgp_process. + (bgp_best_selection) reap REMOVED routes. + (struct bgp_process_queue) Add a field to save the bgp_info. + (bgp_process) Take struct bgp_info as an argument so we can lock + it - probably critical if the route is being removed (but maybe + not) + (bgp_processq_del) unlock the bgp_info + (bgp_rib_withdraw, bgp_rib_remove) make them more consistent with + each other. Don't play games with the VALID flag, bgp_process + is async now, so it didn't make a difference anyway. + Remove the 'force' argument from bgp_rib_withdraw, withdraw+force + is equivalent to bgp_rib_remove. Update all its callers. + (all callers of bgp_process) pass the relevant bgp_info in as an + argument. + (bgp_update_rsclient) bgp_rib_withdraw and force set is same as + bgp_rib_remove. + (route_vty_short_status_out) new helper to print the leading + route-status string used in many command outputs. Consolidate. + (route_vty_out, route_vty_out_tag, damp_route_vty_out, + flap_route_vty_out) use route_vty_short_status_out rather than + duplicate. + (route_vty_out_detail) print state of REMOVED flag. + (BGP_SHOW_SCODE_HEADER) update for Removed flag. + 2005-08-03 Hasso Tepper * bgp_routemap.c: Revert part of leaking communities fix commited in Index: bgp_damp.c =================================================================== RCS file: /var/cvsroot/quagga/bgpd/bgp_damp.c,v retrieving revision 1.4 diff -u -p -r1.4 bgp_damp.c --- bgp_damp.c 28 Jun 2005 12:44:16 -0000 1.4 +++ bgp_damp.c 16 Aug 2005 17:24:41 -0000 @@ -159,7 +159,7 @@ bgp_reuse_timer (struct thread *t) UNSET_FLAG (bdi->binfo->flags, BGP_INFO_HISTORY); bgp_aggregate_increment (bgp, &bdi->rn->p, bdi->binfo, bdi->afi, bdi->safi); - bgp_process (bgp, bdi->rn, bdi->afi, bdi->safi); + bgp_process (bgp, bdi->rn, bdi->binfo, bdi->afi, bdi->safi); } if (bdi->penalty <= damp->reuse_limit / 2.0) Index: bgp_nexthop.c =================================================================== RCS file: /var/cvsroot/quagga/bgpd/bgp_nexthop.c,v retrieving revision 1.14 diff -u -p -r1.14 bgp_nexthop.c --- bgp_nexthop.c 28 Jun 2005 12:44:16 -0000 1.14 +++ bgp_nexthop.c 16 Aug 2005 17:24:41 -0000 @@ -496,7 +496,7 @@ bgp_scan (afi_t afi, safi_t safi) afi, SAFI_UNICAST); } } - bgp_process (bgp, rn, afi, SAFI_UNICAST); + bgp_process (bgp, rn, NULL, afi, SAFI_UNICAST); } /* Flash old cache. */ Index: bgp_route.c =================================================================== RCS file: /var/cvsroot/quagga/bgpd/bgp_route.c,v retrieving revision 1.33 diff -u -p -r1.33 bgp_route.c --- bgp_route.c 28 Jun 2005 12:44:16 -0000 1.33 +++ bgp_route.c 16 Aug 2005 17:24:43 -0000 @@ -164,8 +164,10 @@ bgp_info_add (struct bgp_node *rn, struc peer_lock (ri->peer); /* bgp_info peer reference */ } -void -bgp_info_delete (struct bgp_node *rn, struct bgp_info *ri) +/* Do the actual removal of info from RIB, for use by bgp_process + completion callback *only* */ +static void +bgp_info_remove (struct bgp_node *rn, struct bgp_info *ri) { if (ri->next) ri->next->prev = ri->prev; @@ -178,6 +180,15 @@ bgp_info_delete (struct bgp_node *rn, st bgp_unlock_node (rn); } +void +bgp_info_delete (struct bgp_node *rn, struct bgp_info *ri) +{ + /* leave info in place for now in place for now, + * bgp_process will reap it later. */ + SET_FLAG (ri->flags, BGP_INFO_REMOVED); + UNSET_FLAG (ri->flags, BGP_INFO_VALID); +} + /* Get MED value. If MED value is missing and "bgp bestpath missing-as-worst" is specified, treat it as the worst value. */ static u_int32_t @@ -1097,7 +1108,8 @@ bgp_best_selection (struct bgp *bgp, str struct bgp_info *ri; struct bgp_info *ri1; struct bgp_info *ri2; - + struct bgp_info *nextri = NULL; + /* bgp deterministic-med */ new_select = NULL; if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED)) @@ -1137,13 +1149,19 @@ bgp_best_selection (struct bgp *bgp, str /* Check old selected route and new selected route. */ old_select = NULL; new_select = NULL; - for (ri = rn->info; ri; ri = ri->next) + for (ri = rn->info; (ri != NULL) && (nextri = ri->next, 1); ri = nextri) { if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)) old_select = ri; if (BGP_INFO_HOLDDOWN (ri)) - continue; + { + /* reap REMOVED routes, if needs be */ + if (CHECK_FLAG (ri->flags, BGP_INFO_REMOVED)) + bgp_info_remove (rn, ri); + + continue; + } if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED) && (! CHECK_FLAG (ri->flags, BGP_INFO_DMED_SELECTED))) @@ -1157,7 +1175,7 @@ bgp_best_selection (struct bgp *bgp, str if (bgp_info_cmp (bgp, ri, new_select)) new_select = ri; } - + result->old = old_select; result->new = new_select; @@ -1212,6 +1230,7 @@ struct bgp_process_queue { struct bgp *bgp; struct bgp_node *rn; + struct bgp_info *ri; afi_t afi; safi_t safi; }; @@ -1352,6 +1371,8 @@ bgp_process_main (struct bgp_process_que static void bgp_processq_del (struct bgp_process_queue *pq) { + if (pq->ri) + bgp_info_unlock (pq->ri); /* bgp_processq_del */ bgp_unlock_node (pq->rn); XFREE (MTYPE_BGP_PROCESS_QUEUE, pq); } @@ -1384,7 +1405,8 @@ bgp_process_queue_init (void) } void -bgp_process (struct bgp *bgp, struct bgp_node *rn, afi_t afi, safi_t safi) +bgp_process (struct bgp *bgp, struct bgp_node *rn, struct bgp_info *ri, + afi_t afi, safi_t safi) { struct bgp_process_queue *pqnode; @@ -1402,6 +1424,8 @@ bgp_process (struct bgp *bgp, struct bgp return; pqnode->rn = bgp_lock_node (rn); /* unlocked by bgp_processq_del */ + if (ri) + pqnode->ri = bgp_info_lock (ri); /* unlocked by bgp_processq_del */ pqnode->bgp = bgp; pqnode->afi = afi; pqnode->safi = safi; @@ -1512,56 +1536,55 @@ bgp_maximum_prefix_overflow (struct peer return 0; } +/* Unconditionally remove the route from the RIB, without taking + * damping into consideration (eg, because the session went down) + */ static void bgp_rib_remove (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer, afi_t afi, safi_t safi) { - if (! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY)) + if (!CHECK_FLAG (ri->flags, BGP_INFO_HISTORY) + && rn->table->type == BGP_TABLE_MAIN) { /* Ignore 'pcount' for RS-client tables */ if ( rn->table->type == BGP_TABLE_MAIN) { - peer->pcount[afi][safi]--; - bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi); + peer->pcount[afi][safi]--; + bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi); } - UNSET_FLAG (ri->flags, BGP_INFO_VALID); - bgp_process (peer->bgp, rn, afi, safi); } + bgp_process (peer->bgp, rn, ri, afi, safi); bgp_info_delete (rn, ri); } static void bgp_rib_withdraw (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer, - afi_t afi, safi_t safi, int force) + afi_t afi, safi_t safi) { int valid; int status = BGP_DAMP_NONE; - /* Ignore 'pcount' for RS-client tables */ - if (! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY) && - rn->table->type == BGP_TABLE_MAIN) + if (!CHECK_FLAG (ri->flags, BGP_INFO_HISTORY) + && rn->table->type == BGP_TABLE_MAIN) { - if (! CHECK_FLAG (ri->flags, BGP_INFO_STALE)) - peer->pcount[afi][safi]--; - bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi); - } - - if (! force) - { - if (CHECK_FLAG (peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING) - && peer_sort (peer) == BGP_PEER_EBGP) - status = bgp_damp_withdraw (ri, rn, afi, safi, 0); - - if (status == BGP_DAMP_SUPPRESSED) - return; + /* Ignore 'pcount' for RS-client tables */ + if ( rn->table->type == BGP_TABLE_MAIN) + { + peer->pcount[afi][safi]--; + bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi); + } } + + /* apply dampening, if result is suppressed, we'll be retaining + * the bgp_info in the RIB for historical reference. + */ + if (CHECK_FLAG (peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING) + && peer_sort (peer) == BGP_PEER_EBGP) + if ( (status = bgp_damp_withdraw (ri, rn, afi, safi, 0)) + == BGP_DAMP_SUPPRESSED) + return; - valid = CHECK_FLAG (ri->flags, BGP_INFO_VALID); - UNSET_FLAG (ri->flags, BGP_INFO_VALID); - bgp_process (peer->bgp, rn, afi, safi); - - if (valid) - SET_FLAG (ri->flags, BGP_INFO_VALID); + bgp_process (peer->bgp, rn, ri, afi, safi); if (status != BGP_DAMP_USED) bgp_info_delete (rn, ri); @@ -1692,7 +1715,7 @@ bgp_update_rsclient (struct peer *rsclie SET_FLAG (ri->flags, BGP_INFO_VALID); /* Process change. */ - bgp_process (bgp, rn, afi, safi); + bgp_process (bgp, rn, ri, afi, safi); bgp_unlock_node (rn); return; @@ -1728,7 +1751,7 @@ bgp_update_rsclient (struct peer *rsclie bgp_unlock_node (rn); /* Process change. */ - bgp_process (bgp, rn, afi, safi); + bgp_process (bgp, rn, new, afi, safi); return; @@ -1743,7 +1766,7 @@ bgp_update_rsclient (struct peer *rsclie p->prefixlen, rsclient->host, reason); if (ri) - bgp_rib_withdraw (rn, ri, peer, afi, safi, 1); + bgp_rib_remove (rn, ri, peer, afi, safi); bgp_unlock_node (rn); @@ -1771,7 +1794,7 @@ bgp_withdraw_rsclient (struct peer *rscl /* Withdraw specified route from routing table. */ if (ri && ! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY)) - bgp_rib_withdraw (rn, ri, peer, afi, safi, 0); + bgp_rib_withdraw (rn, ri, peer, afi, safi); else if (BGP_DEBUG (update, UPDATE_IN)) zlog (peer->log, LOG_DEBUG, "%s Can't find the route %s/%d", peer->host, @@ -1917,7 +1940,7 @@ bgp_update_main (struct peer *peer, stru if (ret != BGP_DAMP_SUPPRESSED) { bgp_aggregate_increment (bgp, p, ri, afi, safi); - bgp_process (bgp, rn, afi, safi); + bgp_process (bgp, rn, ri, afi, safi); } } else @@ -2012,7 +2035,7 @@ bgp_update_main (struct peer *peer, stru /* Process change. */ bgp_aggregate_increment (bgp, p, ri, afi, safi); - bgp_process (bgp, rn, afi, safi); + bgp_process (bgp, rn, ri, afi, safi); bgp_unlock_node (rn); return 0; } @@ -2071,7 +2094,7 @@ bgp_update_main (struct peer *peer, stru return -1; /* Process change. */ - bgp_process (bgp, rn, afi, safi); + bgp_process (bgp, rn, new, afi, safi); return 0; @@ -2086,7 +2109,7 @@ bgp_update_main (struct peer *peer, stru p->prefixlen, reason); if (ri) - bgp_rib_withdraw (rn, ri, peer, afi, safi, 1); + bgp_rib_remove (rn, ri, peer, afi, safi); bgp_unlock_node (rn); @@ -2163,7 +2186,7 @@ bgp_withdraw (struct peer *peer, struct /* Withdraw specified route from routing table. */ if (ri && ! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY)) - bgp_rib_withdraw (rn, ri, peer, afi, safi, 0); + bgp_rib_withdraw (rn, ri, peer, afi, safi); else if (BGP_DEBUG (update, UPDATE_IN)) zlog (peer->log, LOG_DEBUG, "%s Can't find the route %s/%d", peer->host, @@ -2848,7 +2871,7 @@ bgp_static_withdraw_rsclient (struct bgp if (ri) { UNSET_FLAG (ri->flags, BGP_INFO_VALID); - bgp_process (bgp, rn, afi, safi); + bgp_process (bgp, rn, ri, afi, safi); bgp_info_delete (rn, ri); } @@ -2967,7 +2990,7 @@ bgp_static_update_rsclient (struct peer ri->uptime = time (NULL); /* Process change. */ - bgp_process (bgp, rn, afi, safi); + bgp_process (bgp, rn, ri, afi, safi); bgp_unlock_node (rn); aspath_unintern (attr.aspath); return; @@ -2990,7 +3013,7 @@ bgp_static_update_rsclient (struct peer bgp_unlock_node (rn); /* Process change. */ - bgp_process (bgp, rn, afi, safi); + bgp_process (bgp, rn, new, afi, safi); /* Unintern original. */ aspath_unintern (attr.aspath); @@ -3074,7 +3097,7 @@ bgp_static_update_main (struct bgp *bgp, /* Process change. */ bgp_aggregate_increment (bgp, p, ri, afi, safi); - bgp_process (bgp, rn, afi, safi); + bgp_process (bgp, rn, ri, afi, safi); bgp_unlock_node (rn); aspath_unintern (attr.aspath); return; @@ -3100,7 +3123,7 @@ bgp_static_update_main (struct bgp *bgp, bgp_unlock_node (rn); /* Process change. */ - bgp_process (bgp, rn, afi, safi); + bgp_process (bgp, rn, new, afi, safi); /* Unintern original. */ aspath_unintern (attr.aspath); @@ -3150,7 +3173,7 @@ bgp_static_update_vpnv4 (struct bgp *bgp bgp_unlock_node (rn); /* Process change. */ - bgp_process (bgp, rn, afi, safi); + bgp_process (bgp, rn, new, afi, safi); } void @@ -3174,7 +3197,7 @@ bgp_static_withdraw (struct bgp *bgp, st { bgp_aggregate_decrement (bgp, p, ri, afi, safi); UNSET_FLAG (ri->flags, BGP_INFO_VALID); - bgp_process (bgp, rn, afi, safi); + bgp_process (bgp, rn, ri, afi, safi); bgp_info_delete (rn, ri); } @@ -3223,7 +3246,7 @@ bgp_static_withdraw_vpnv4 (struct bgp *b { bgp_aggregate_decrement (bgp, p, ri, afi, safi); UNSET_FLAG (ri->flags, BGP_INFO_VALID); - bgp_process (bgp, rn, afi, safi); + bgp_process (bgp, rn, ri, afi, safi); bgp_info_delete (rn, ri); } @@ -4041,7 +4064,7 @@ bgp_aggregate_route (struct bgp *bgp, st } } if (match) - bgp_process (bgp, rn, afi, safi); + bgp_process (bgp, rn, NULL, afi, safi); } bgp_unlock_node (top); @@ -4094,7 +4117,7 @@ bgp_aggregate_route (struct bgp *bgp, st bgp_info_add (rn, new); bgp_unlock_node (rn); - bgp_process (bgp, rn, afi, safi); + bgp_process (bgp, rn, new, afi, safi); } else { @@ -4246,7 +4269,7 @@ bgp_aggregate_add (struct bgp *bgp, stru /* If this node is suppressed, process the change. */ if (match) - bgp_process (bgp, rn, afi, safi); + bgp_process (bgp, rn, ri, afi, safi); } bgp_unlock_node (top); @@ -4267,7 +4290,7 @@ bgp_aggregate_add (struct bgp *bgp, stru bgp_unlock_node (rn); /* Process change. */ - bgp_process (bgp, rn, afi, safi); + bgp_process (bgp, rn, new, afi, safi); } } @@ -4318,7 +4341,7 @@ bgp_aggregate_delete (struct bgp *bgp, s /* If this node is suppressed, process the change. */ if (match) - bgp_process (bgp, rn, afi, safi); + bgp_process (bgp, rn, ri, afi, safi); } bgp_unlock_node (top); @@ -4335,7 +4358,7 @@ bgp_aggregate_delete (struct bgp *bgp, s if (ri) { UNSET_FLAG (ri->flags, BGP_INFO_VALID); - bgp_process (bgp, rn, afi, safi); + bgp_process (bgp, rn, ri, afi, safi); bgp_info_delete (rn, ri); } @@ -4870,7 +4893,7 @@ bgp_redistribute_add (struct prefix *p, /* Process change. */ bgp_aggregate_increment (bgp, p, bi, afi, SAFI_UNICAST); - bgp_process (bgp, bn, afi, SAFI_UNICAST); + bgp_process (bgp, bn, bi, afi, SAFI_UNICAST); bgp_unlock_node (bn); aspath_unintern (attr.aspath); return; @@ -4888,7 +4911,7 @@ bgp_redistribute_add (struct prefix *p, bgp_aggregate_increment (bgp, p, new, afi, SAFI_UNICAST); bgp_info_add (bn, new); bgp_unlock_node (bn); - bgp_process (bgp, bn, afi, SAFI_UNICAST); + bgp_process (bgp, bn, new, afi, SAFI_UNICAST); } } @@ -4922,7 +4945,7 @@ bgp_redistribute_delete (struct prefix * { bgp_aggregate_decrement (bgp, p, ri, afi, SAFI_UNICAST); UNSET_FLAG (ri->flags, BGP_INFO_VALID); - bgp_process (bgp, rn, afi, SAFI_UNICAST); + bgp_process (bgp, rn, ri, afi, SAFI_UNICAST); bgp_info_delete (rn, ri); } bgp_unlock_node (rn); @@ -4951,7 +4974,7 @@ bgp_redistribute_withdraw (struct bgp *b { bgp_aggregate_decrement (bgp, &rn->p, ri, afi, SAFI_UNICAST); UNSET_FLAG (ri->flags, BGP_INFO_VALID); - bgp_process (bgp, rn, afi, SAFI_UNICAST); + bgp_process (bgp, rn, ri, afi, SAFI_UNICAST); bgp_info_delete (rn, ri); } } @@ -4996,15 +5019,14 @@ enum bgp_display_type normal_list, }; -/* called from terminal list command */ -void -route_vty_out (struct vty *vty, struct prefix *p, - struct bgp_info *binfo, int display, safi_t safi) +/* Print the short form route status for a bgp_info */ +static void +route_vty_short_status_out (struct vty *vty, struct bgp_info *binfo) { - struct attr *attr; - - /* Route status display. */ - if (CHECK_FLAG (binfo->flags, BGP_INFO_STALE)) + /* Route status display. */ + if (CHECK_FLAG (binfo->flags, BGP_INFO_REMOVED)) + vty_out (vty, "R"); + else if (CHECK_FLAG (binfo->flags, BGP_INFO_STALE)) vty_out (vty, "S"); else if (binfo->suppress) vty_out (vty, "s"); @@ -5027,7 +5049,18 @@ route_vty_out (struct vty *vty, struct p if ((binfo->peer->as) && (binfo->peer->as == binfo->peer->local_as)) vty_out (vty, "i"); else - vty_out (vty, " "); + vty_out (vty, " "); +} + +/* called from terminal list command */ +void +route_vty_out (struct vty *vty, struct prefix *p, + struct bgp_info *binfo, int display, safi_t safi) +{ + struct attr *attr; + + /* short status lead text */ + route_vty_short_status_out (vty, binfo); /* print prefix and mask */ if (! display) @@ -5159,30 +5192,9 @@ route_vty_out_tag (struct vty *vty, stru struct attr *attr; u_int32_t label = 0; - /* Route status display. */ - if (binfo->suppress) - vty_out (vty, "s"); - else if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY)) - vty_out (vty, "*"); - else - vty_out (vty, " "); - - /* Selected */ - if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY)) - vty_out (vty, "h"); - else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED)) - vty_out (vty, "d"); - else if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED)) - vty_out (vty, ">"); - else - vty_out (vty, " "); - - /* Internal route. */ - if ((binfo->peer->as) && (binfo->peer->as == binfo->peer->local_as)) - vty_out (vty, "i"); - else - vty_out (vty, " "); - + /* short status lead text */ + route_vty_short_status_out (vty, binfo); + /* print prefix and mask */ if (! display) route_vty_out_route (p, vty); @@ -5232,26 +5244,9 @@ damp_route_vty_out (struct vty *vty, str struct attr *attr; int len; - /* Route status display. */ - if (binfo->suppress) - vty_out (vty, "s"); - else if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY)) - vty_out (vty, "*"); - else - vty_out (vty, " "); - - /* Selected */ - if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY)) - vty_out (vty, "h"); - else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED)) - vty_out (vty, "d"); - else if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED)) - vty_out (vty, ">"); - else - vty_out (vty, " "); - - vty_out (vty, " "); - + /* short status lead text */ + route_vty_short_status_out (vty, binfo); + /* print prefix and mask */ if (! display) route_vty_out_route (p, vty); @@ -5298,26 +5293,9 @@ flap_route_vty_out (struct vty *vty, str bdi = binfo->damp_info; - /* Route status display. */ - if (binfo->suppress) - vty_out (vty, "s"); - else if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY)) - vty_out (vty, "*"); - else - vty_out (vty, " "); - - /* Selected */ - if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY)) - vty_out (vty, "h"); - else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED)) - vty_out (vty, "d"); - else if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED)) - vty_out (vty, ">"); - else - vty_out (vty, " "); - - vty_out (vty, " "); - + /* short status lead text */ + route_vty_short_status_out (vty, binfo); + /* print prefix and mask */ if (! display) route_vty_out_route (p, vty); @@ -5387,6 +5365,8 @@ route_vty_out_detail (struct vty *vty, s aspath_print_vty (vty, attr->aspath); } + if (CHECK_FLAG (binfo->flags, BGP_INFO_REMOVED)) + vty_out (vty, ", (removed)"); if (CHECK_FLAG (binfo->flags, BGP_INFO_STALE)) vty_out (vty, ", (stale)"); if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR))) @@ -5525,7 +5505,7 @@ route_vty_out_detail (struct vty *vty, s vty_out (vty, "%s", VTY_NEWLINE); } -#define BGP_SHOW_SCODE_HEADER "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,%s r RIB-failure, S Stale%s" +#define BGP_SHOW_SCODE_HEADER "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,%s r RIB-failure, S Stale, R Removed%s" #define BGP_SHOW_OCODE_HEADER "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s" #define BGP_SHOW_HEADER " Network Next Hop Metric LocPrf Weight Path%s" #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path%s" Index: bgp_route.h =================================================================== RCS file: /var/cvsroot/quagga/bgpd/bgp_route.h,v retrieving revision 1.10 diff -u -p -r1.10 bgp_route.h --- bgp_route.h 28 Jun 2005 12:44:17 -0000 1.10 +++ bgp_route.h 16 Aug 2005 17:24:43 -0000 @@ -54,6 +54,7 @@ struct bgp_info #define BGP_INFO_DMED_CHECK (1 << 6) #define BGP_INFO_DMED_SELECTED (1 << 7) #define BGP_INFO_STALE (1 << 8) +#define BGP_INFO_REMOVED (1 << 9) /* Peer structure. */ struct peer *peer; @@ -178,8 +179,8 @@ extern int bgp_withdraw (struct peer *, afi_t, safi_t, int, int, struct prefix_rd *, u_char *); /* for bgp_nexthop and bgp_damp */ -extern void bgp_process (struct bgp *, struct bgp_node *, afi_t, safi_t); - +extern void bgp_process (struct bgp *, struct bgp_node *, struct bgp_info *, + afi_t, safi_t); extern int bgp_config_write_network (struct vty *, struct bgp *, afi_t, safi_t, int *); extern int bgp_config_write_distance (struct vty *, struct bgp *); Index: bgpd.h =================================================================== RCS file: /var/cvsroot/quagga/bgpd/bgpd.h,v retrieving revision 1.23 diff -u -p -r1.23 bgpd.h --- bgpd.h 28 Jun 2005 12:44:17 -0000 1.23 +++ bgpd.h 16 Aug 2005 17:24:43 -0000 @@ -742,7 +742,8 @@ enum bgp_clear_type #define BGP_INFO_HOLDDOWN(BI) \ (! CHECK_FLAG ((BI)->flags, BGP_INFO_VALID) \ || CHECK_FLAG ((BI)->flags, BGP_INFO_HISTORY) \ - || CHECK_FLAG ((BI)->flags, BGP_INFO_DAMPED)) + || CHECK_FLAG ((BI)->flags, BGP_INFO_DAMPED) \ + || CHECK_FLAG ((BI)->flags, BGP_INFO_REMOVED)) /* Count prefix size from mask length */ #define PSIZE(a) (((a) + 7) / (8))