diff options
-rw-r--r-- | bgpd/ChangeLog | 13 | ||||
-rw-r--r-- | bgpd/bgp_route.c | 124 | ||||
-rw-r--r-- | bgpd/bgp_route.h | 1 |
3 files changed, 87 insertions, 51 deletions
diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog index 714de1d3..8e2a397d 100644 --- a/bgpd/ChangeLog +++ b/bgpd/ChangeLog @@ -1,3 +1,16 @@ +2006-02-05 Paul Jakma <paul.jakma@sun.com> + + * bgp_route.h: Add BGP_INFO_COUNTED to track whether + prefix has been counted or not. + * bgp_route.c: (bgp_pcount_{inc,dec}rement) new helpers, to + centralise inc/dec of prefix-count, + (bgp_rib_remove) Remove pcount decrement, use helper. + (bgp_rib_withdraw) ditto, additionally use previous function + too. + (bgp_update_main) Use pcount helpers. + (bgp_clear_route_node) ditto, aslo REMOVED routes don't need + clearing. + 2006-02-02 Paul Jakma <paul.jakma@sun.com> * bgp_route.c: (bgp_{clear_node,process}_queue_init) delay diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 3d9856b9..ba6412ee 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -1554,6 +1554,43 @@ bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi, return 0; } +static void +bgp_pcount_increment (struct bgp_node *rn, struct bgp_info *ri, + afi_t afi, safi_t safi) +{ + assert (ri && rn); + + if (!CHECK_FLAG (ri->flags, BGP_INFO_COUNTED) + && rn->table->type == BGP_TABLE_MAIN) + { + SET_FLAG (ri->flags, BGP_INFO_COUNTED); + ri->peer->pcount[afi][safi]++; + } +} + +static void +bgp_pcount_decrement (struct bgp_node *rn, struct bgp_info *ri, + afi_t afi, safi_t safi) +{ + /* Ignore 'pcount' for RS-client tables */ + if (CHECK_FLAG (ri->flags, BGP_INFO_COUNTED) + && rn->table->type == BGP_TABLE_MAIN) + { + UNSET_FLAG (ri->flags, BGP_INFO_COUNTED); + + /* slight hack, but more robust against errors. */ + if (ri->peer->pcount[afi][safi]) + ri->peer->pcount[afi][safi]--; + else + { + zlog_warn ("%s: Asked to decrement 0 prefix count for peer %s", + __func__, ri->peer->host); + zlog_backtrace (LOG_WARNING); + zlog_warn ("%s: Please report to Quagga bugzilla", __func__); + } + } +} + /* Unconditionally remove the route from the RIB, without taking * damping into consideration (eg, because the session went down) */ @@ -1561,18 +1598,13 @@ 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) - && 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); - } - } + bgp_pcount_decrement (rn, ri, afi, safi); + bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi); + + if (!CHECK_FLAG (ri->flags, BGP_INFO_HISTORY)) + bgp_info_delete (rn, ri); /* keep historical info */ + bgp_process (peer->bgp, rn, afi, safi); - bgp_info_delete (rn, ri); } static void @@ -1581,17 +1613,6 @@ bgp_rib_withdraw (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer, { int status = BGP_DAMP_NONE; - 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); - } - } - /* apply dampening, if result is suppressed, we'll be retaining * the bgp_info in the RIB for historical reference. */ @@ -1599,12 +1620,13 @@ bgp_rib_withdraw (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer, && peer_sort (peer) == BGP_PEER_EBGP) if ( (status = bgp_damp_withdraw (ri, rn, afi, safi, 0)) == BGP_DAMP_SUPPRESSED) - return; - - bgp_process (peer->bgp, rn, afi, safi); - - if (status != BGP_DAMP_USED) - bgp_info_delete (rn, ri); + { + bgp_pcount_decrement (rn, ri, afi, safi); + bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi); + return; + } + + bgp_rib_remove (rn, ri, peer, afi, safi); } static void @@ -1952,13 +1974,13 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr, inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN), p->prefixlen); - peer->pcount[afi][safi]++; - ret = bgp_damp_update (ri, rn, afi, safi); - if (ret != BGP_DAMP_SUPPRESSED) - { - bgp_aggregate_increment (bgp, p, ri, afi, safi); - bgp_process (bgp, rn, afi, safi); - } + bgp_pcount_increment (rn, ri, afi, safi); + + if (bgp_damp_update (ri, rn, afi, safi) != BGP_DAMP_SUPPRESSED) + { + bgp_aggregate_increment (bgp, p, ri, afi, safi); + bgp_process (bgp, rn, afi, safi); + } } else { @@ -1973,7 +1995,8 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr, if (CHECK_FLAG (ri->flags, BGP_INFO_STALE)) { UNSET_FLAG (ri->flags, BGP_INFO_STALE); - peer->pcount[afi][safi]++; + bgp_pcount_increment (rn, ri, afi, safi); + bgp_process (bgp, rn, afi, safi); } } @@ -1991,14 +2014,17 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr, /* graceful restart STALE flag unset. */ if (CHECK_FLAG (ri->flags, BGP_INFO_STALE)) - { - UNSET_FLAG (ri->flags, BGP_INFO_STALE); - peer->pcount[afi][safi]++; - } + UNSET_FLAG (ri->flags, BGP_INFO_STALE); /* The attribute is changed. */ SET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED); - + + /* implicit withdraw, decrement aggregate and pcount here. + * only if update is accepted, they'll increment below. + */ + bgp_pcount_decrement (rn, ri, afi, safi); + bgp_aggregate_decrement (bgp, p, ri, afi, safi); + /* Update bgp route dampening information. */ if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING) && peer_sort (peer) == BGP_PEER_EBGP) @@ -2007,12 +2033,8 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr, information. */ if (! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY)) bgp_damp_withdraw (ri, rn, afi, safi, 1); - else - peer->pcount[afi][safi]++; } - bgp_aggregate_decrement (bgp, p, ri, afi, safi); - /* Update to new attribute. */ bgp_attr_unintern (ri->attr); ri->attr = attr_new; @@ -2050,6 +2072,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr, SET_FLAG (ri->flags, BGP_INFO_VALID); /* Process change. */ + bgp_pcount_increment (rn, ri, afi, safi); bgp_aggregate_increment (bgp, p, ri, afi, safi); bgp_process (bgp, rn, afi, safi); @@ -2066,9 +2089,6 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr, p->prefixlen); } - /* Increment prefix counter */ - peer->pcount[afi][safi]++; - /* Make new BGP info. */ new = bgp_info_new (); new->type = type; @@ -2096,7 +2116,8 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr, else SET_FLAG (new->flags, BGP_INFO_VALID); - /* Aggregate address increment. */ + /* Increment prefix */ + bgp_pcount_increment (rn, new, afi, safi); bgp_aggregate_increment (bgp, p, new, afi, safi); /* Register new BGP information. */ @@ -2469,10 +2490,11 @@ bgp_clear_route_node (struct work_queue *wq, void *data) && cq->peer->nsf[cq->afi][cq->safi] && ! CHECK_FLAG (ri->flags, BGP_INFO_STALE) && ! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY) - && ! CHECK_FLAG (ri->flags, BGP_INFO_DAMPED)) + && ! CHECK_FLAG (ri->flags, BGP_INFO_DAMPED) + && ! CHECK_FLAG (ri->flags, BGP_INFO_REMOVED)) { + bgp_pcount_decrement (cq->rn, ri, cq->afi, cq->safi); SET_FLAG (ri->flags, BGP_INFO_STALE); - cq->peer->pcount[cq->afi][cq->safi]--; } else bgp_rib_remove (cq->rn, ri, cq->peer, cq->afi, cq->safi); diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index aa2c59ec..24be30ff 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -55,6 +55,7 @@ struct bgp_info #define BGP_INFO_DMED_SELECTED (1 << 7) #define BGP_INFO_STALE (1 << 8) #define BGP_INFO_REMOVED (1 << 9) +#define BGP_INFO_COUNTED (1 << 10) /* Peer structure. */ struct peer *peer; |