diff options
author | whitespace / reindent <invalid@invalid.invalid> | 2017-07-17 14:03:14 +0200 |
---|---|---|
committer | whitespace / reindent <invalid@invalid.invalid> | 2017-07-17 14:04:07 +0200 |
commit | d62a17aedeb0eebdba98238874bb13d62c48dbf9 (patch) | |
tree | 3b319b1d61c8b85b4d1f06adf8b844bb8a9b5107 /bgpd/bgp_damp.c | |
parent | *: add indent control files (diff) | |
download | frr-d62a17aedeb0eebdba98238874bb13d62c48dbf9.tar.xz frr-d62a17aedeb0eebdba98238874bb13d62c48dbf9.zip |
*: reindentreindent-master-after
indent.py `git ls-files | pcregrep '\.[ch]$' | pcregrep -v '^(ldpd|babeld|nhrpd)/'`
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'bgpd/bgp_damp.c')
-rw-r--r-- | bgpd/bgp_damp.c | 1125 |
1 files changed, 552 insertions, 573 deletions
diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index d276de6eb..bd3ae27c0 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -33,7 +33,7 @@ #include "bgpd/bgp_damp.h" #include "bgpd/bgp_table.h" #include "bgpd/bgp_route.h" -#include "bgpd/bgp_attr.h" +#include "bgpd/bgp_attr.h" #include "bgpd/bgp_advertise.h" /* Global variable to access damping configuration */ @@ -46,672 +46,651 @@ static struct bgp_damp_config *damp = &bgp_damp_cfg; #define BGP_DAMP_LIST_DEL(N,A) BGP_INFO_DEL(N,A,no_reuse_list) /* Calculate reuse list index by penalty value. */ -static int -bgp_reuse_index (int penalty) +static int bgp_reuse_index(int penalty) { - unsigned int i; - int index; + unsigned int i; + int index; - i = (int)(((double) penalty / damp->reuse_limit - 1.0) * damp->scale_factor); - - if ( i >= damp->reuse_index_size ) - i = damp->reuse_index_size - 1; + i = (int)(((double)penalty / damp->reuse_limit - 1.0) + * damp->scale_factor); - index = damp->reuse_index[i] - damp->reuse_index[0]; + if (i >= damp->reuse_index_size) + i = damp->reuse_index_size - 1; - return (damp->reuse_offset + index) % damp->reuse_list_size; + index = damp->reuse_index[i] - damp->reuse_index[0]; + + return (damp->reuse_offset + index) % damp->reuse_list_size; } /* Add BGP dampening information to reuse list. */ -static void -bgp_reuse_list_add (struct bgp_damp_info *bdi) +static void bgp_reuse_list_add(struct bgp_damp_info *bdi) { - int index; + int index; - index = bdi->index = bgp_reuse_index (bdi->penalty); + index = bdi->index = bgp_reuse_index(bdi->penalty); - bdi->prev = NULL; - bdi->next = damp->reuse_list[index]; - if (damp->reuse_list[index]) - damp->reuse_list[index]->prev = bdi; - damp->reuse_list[index] = bdi; + bdi->prev = NULL; + bdi->next = damp->reuse_list[index]; + if (damp->reuse_list[index]) + damp->reuse_list[index]->prev = bdi; + damp->reuse_list[index] = bdi; } /* Delete BGP dampening information from reuse list. */ -static void -bgp_reuse_list_delete (struct bgp_damp_info *bdi) +static void bgp_reuse_list_delete(struct bgp_damp_info *bdi) { - if (bdi->next) - bdi->next->prev = bdi->prev; - if (bdi->prev) - bdi->prev->next = bdi->next; - else - damp->reuse_list[bdi->index] = bdi->next; -} + if (bdi->next) + bdi->next->prev = bdi->prev; + if (bdi->prev) + bdi->prev->next = bdi->next; + else + damp->reuse_list[bdi->index] = bdi->next; +} /* Return decayed penalty value. */ -int -bgp_damp_decay (time_t tdiff, int penalty) +int bgp_damp_decay(time_t tdiff, int penalty) { - unsigned int i; + unsigned int i; + + i = (int)((double)tdiff / DELTA_T); - i = (int) ((double) tdiff / DELTA_T); + if (i == 0) + return penalty; - if (i == 0) - return penalty; - - if (i >= damp->decay_array_size) - return 0; + if (i >= damp->decay_array_size) + return 0; - return (int) (penalty * damp->decay_array[i]); + return (int)(penalty * damp->decay_array[i]); } /* Handler of reuse timer event. Each route in the current reuse-list is evaluated. RFC2439 Section 4.8.7. */ -static int -bgp_reuse_timer (struct thread *t) +static int bgp_reuse_timer(struct thread *t) { - struct bgp_damp_info *bdi; - struct bgp_damp_info *next; - time_t t_now, t_diff; - - damp->t_reuse = NULL; - thread_add_timer(bm->master, bgp_reuse_timer, NULL, DELTA_REUSE, - &damp->t_reuse); - - t_now = bgp_clock (); - - /* 1. save a pointer to the current zeroth queue head and zero the - list head entry. */ - bdi = damp->reuse_list[damp->reuse_offset]; - damp->reuse_list[damp->reuse_offset] = NULL; - - /* 2. set offset = modulo reuse-list-size ( offset + 1 ), thereby - rotating the circular queue of list-heads. */ - damp->reuse_offset = (damp->reuse_offset + 1) % damp->reuse_list_size; - - /* 3. if ( the saved list head pointer is non-empty ) */ - for (; bdi; bdi = next) - { - struct bgp *bgp = bdi->binfo->peer->bgp; - - next = bdi->next; - - /* Set t-diff = t-now - t-updated. */ - t_diff = t_now - bdi->t_updated; - - /* Set figure-of-merit = figure-of-merit * decay-array-ok [t-diff] */ - bdi->penalty = bgp_damp_decay (t_diff, bdi->penalty); - - /* Set t-updated = t-now. */ - bdi->t_updated = t_now; - - /* if (figure-of-merit < reuse). */ - if (bdi->penalty < damp->reuse_limit) - { - /* Reuse the route. */ - bgp_info_unset_flag (bdi->rn, bdi->binfo, BGP_INFO_DAMPED); - bdi->suppress_time = 0; - - if (bdi->lastrecord == BGP_RECORD_UPDATE) - { - bgp_info_unset_flag (bdi->rn, bdi->binfo, 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); - } - - if (bdi->penalty <= damp->reuse_limit / 2.0) - bgp_damp_info_free (bdi, 1); - else - BGP_DAMP_LIST_ADD (damp, bdi); + struct bgp_damp_info *bdi; + struct bgp_damp_info *next; + time_t t_now, t_diff; + + damp->t_reuse = NULL; + thread_add_timer(bm->master, bgp_reuse_timer, NULL, DELTA_REUSE, + &damp->t_reuse); + + t_now = bgp_clock(); + + /* 1. save a pointer to the current zeroth queue head and zero the + list head entry. */ + bdi = damp->reuse_list[damp->reuse_offset]; + damp->reuse_list[damp->reuse_offset] = NULL; + + /* 2. set offset = modulo reuse-list-size ( offset + 1 ), thereby + rotating the circular queue of list-heads. */ + damp->reuse_offset = (damp->reuse_offset + 1) % damp->reuse_list_size; + + /* 3. if ( the saved list head pointer is non-empty ) */ + for (; bdi; bdi = next) { + struct bgp *bgp = bdi->binfo->peer->bgp; + + next = bdi->next; + + /* Set t-diff = t-now - t-updated. */ + t_diff = t_now - bdi->t_updated; + + /* Set figure-of-merit = figure-of-merit * decay-array-ok + * [t-diff] */ + bdi->penalty = bgp_damp_decay(t_diff, bdi->penalty); + + /* Set t-updated = t-now. */ + bdi->t_updated = t_now; + + /* if (figure-of-merit < reuse). */ + if (bdi->penalty < damp->reuse_limit) { + /* Reuse the route. */ + bgp_info_unset_flag(bdi->rn, bdi->binfo, + BGP_INFO_DAMPED); + bdi->suppress_time = 0; + + if (bdi->lastrecord == BGP_RECORD_UPDATE) { + bgp_info_unset_flag(bdi->rn, bdi->binfo, + 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); + } + + if (bdi->penalty <= damp->reuse_limit / 2.0) + bgp_damp_info_free(bdi, 1); + else + BGP_DAMP_LIST_ADD(damp, bdi); + } else + /* Re-insert into another list (See RFC2439 Section + * 4.8.6). */ + bgp_reuse_list_add(bdi); } - else - /* Re-insert into another list (See RFC2439 Section 4.8.6). */ - bgp_reuse_list_add (bdi); - } - return 0; + return 0; } /* A route becomes unreachable (RFC2439 Section 4.8.2). */ -int -bgp_damp_withdraw (struct bgp_info *binfo, struct bgp_node *rn, - afi_t afi, safi_t safi, int attr_change) +int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi, + safi_t safi, int attr_change) { - time_t t_now; - struct bgp_damp_info *bdi = NULL; - double last_penalty = 0; - - t_now = bgp_clock (); - - /* Processing Unreachable Messages. */ - if (binfo->extra) - bdi = binfo->extra->damp_info; - - if (bdi == NULL) - { - /* If there is no previous stability history. */ - - /* RFC2439 said: - 1. allocate a damping structure. - 2. set figure-of-merit = 1. - 3. withdraw the route. */ - - bdi = XCALLOC (MTYPE_BGP_DAMP_INFO, sizeof (struct bgp_damp_info)); - bdi->binfo = binfo; - bdi->rn = rn; - bdi->penalty = (attr_change ? DEFAULT_PENALTY / 2 : DEFAULT_PENALTY); - bdi->flap = 1; - bdi->start_time = t_now; - bdi->suppress_time = 0; - bdi->index = -1; - bdi->afi = afi; - bdi->safi = safi; - (bgp_info_extra_get (binfo))->damp_info = bdi; - BGP_DAMP_LIST_ADD (damp, bdi); - } - else - { - last_penalty = bdi->penalty; - - /* 1. Set t-diff = t-now - t-updated. */ - bdi->penalty = - (bgp_damp_decay (t_now - bdi->t_updated, bdi->penalty) - + (attr_change ? DEFAULT_PENALTY / 2 : DEFAULT_PENALTY)); - - if (bdi->penalty > damp->ceiling) - bdi->penalty = damp->ceiling; - - bdi->flap++; - } - - assert ((rn == bdi->rn) && (binfo == bdi->binfo)); - - bdi->lastrecord = BGP_RECORD_WITHDRAW; - bdi->t_updated = t_now; - - /* Make this route as historical status. */ - bgp_info_set_flag (rn, binfo, BGP_INFO_HISTORY); - - /* Remove the route from a reuse list if it is on one. */ - if (CHECK_FLAG (bdi->binfo->flags, BGP_INFO_DAMPED)) - { - /* If decay rate isn't equal to 0, reinsert brn. */ - if (bdi->penalty != last_penalty) - { - bgp_reuse_list_delete (bdi); - bgp_reuse_list_add (bdi); + time_t t_now; + struct bgp_damp_info *bdi = NULL; + double last_penalty = 0; + + t_now = bgp_clock(); + + /* Processing Unreachable Messages. */ + if (binfo->extra) + bdi = binfo->extra->damp_info; + + if (bdi == NULL) { + /* If there is no previous stability history. */ + + /* RFC2439 said: + 1. allocate a damping structure. + 2. set figure-of-merit = 1. + 3. withdraw the route. */ + + bdi = XCALLOC(MTYPE_BGP_DAMP_INFO, + sizeof(struct bgp_damp_info)); + bdi->binfo = binfo; + bdi->rn = rn; + bdi->penalty = + (attr_change ? DEFAULT_PENALTY / 2 : DEFAULT_PENALTY); + bdi->flap = 1; + bdi->start_time = t_now; + bdi->suppress_time = 0; + bdi->index = -1; + bdi->afi = afi; + bdi->safi = safi; + (bgp_info_extra_get(binfo))->damp_info = bdi; + BGP_DAMP_LIST_ADD(damp, bdi); + } else { + last_penalty = bdi->penalty; + + /* 1. Set t-diff = t-now - t-updated. */ + bdi->penalty = + (bgp_damp_decay(t_now - bdi->t_updated, bdi->penalty) + + (attr_change ? DEFAULT_PENALTY / 2 + : DEFAULT_PENALTY)); + + if (bdi->penalty > damp->ceiling) + bdi->penalty = damp->ceiling; + + bdi->flap++; + } + + assert((rn == bdi->rn) && (binfo == bdi->binfo)); + + bdi->lastrecord = BGP_RECORD_WITHDRAW; + bdi->t_updated = t_now; + + /* Make this route as historical status. */ + bgp_info_set_flag(rn, binfo, BGP_INFO_HISTORY); + + /* Remove the route from a reuse list if it is on one. */ + if (CHECK_FLAG(bdi->binfo->flags, BGP_INFO_DAMPED)) { + /* If decay rate isn't equal to 0, reinsert brn. */ + if (bdi->penalty != last_penalty) { + bgp_reuse_list_delete(bdi); + bgp_reuse_list_add(bdi); + } + return BGP_DAMP_SUPPRESSED; } - return BGP_DAMP_SUPPRESSED; - } - - /* If not suppressed before, do annonunce this withdraw and - insert into reuse_list. */ - if (bdi->penalty >= damp->suppress_value) - { - bgp_info_set_flag (rn, binfo, BGP_INFO_DAMPED); - bdi->suppress_time = t_now; - BGP_DAMP_LIST_DEL (damp, bdi); - bgp_reuse_list_add (bdi); - } - - return BGP_DAMP_USED; + + /* If not suppressed before, do annonunce this withdraw and + insert into reuse_list. */ + if (bdi->penalty >= damp->suppress_value) { + bgp_info_set_flag(rn, binfo, BGP_INFO_DAMPED); + bdi->suppress_time = t_now; + BGP_DAMP_LIST_DEL(damp, bdi); + bgp_reuse_list_add(bdi); + } + + return BGP_DAMP_USED; } -int -bgp_damp_update (struct bgp_info *binfo, struct bgp_node *rn, - afi_t afi, safi_t safi) +int bgp_damp_update(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi, + safi_t safi) { - time_t t_now; - struct bgp_damp_info *bdi; - int status; - - if (!binfo->extra || !((bdi = binfo->extra->damp_info))) - return BGP_DAMP_USED; - - t_now = bgp_clock (); - bgp_info_unset_flag (rn, binfo, BGP_INFO_HISTORY); - - bdi->lastrecord = BGP_RECORD_UPDATE; - bdi->penalty = bgp_damp_decay (t_now - bdi->t_updated, bdi->penalty); - - if (! CHECK_FLAG (bdi->binfo->flags, BGP_INFO_DAMPED) - && (bdi->penalty < damp->suppress_value)) - status = BGP_DAMP_USED; - else if (CHECK_FLAG (bdi->binfo->flags, BGP_INFO_DAMPED) - && (bdi->penalty < damp->reuse_limit) ) - { - bgp_info_unset_flag (rn, binfo, BGP_INFO_DAMPED); - bgp_reuse_list_delete (bdi); - BGP_DAMP_LIST_ADD (damp, bdi); - bdi->suppress_time = 0; - status = BGP_DAMP_USED; - } - else - status = BGP_DAMP_SUPPRESSED; - - if (bdi->penalty > damp->reuse_limit / 2.0) - bdi->t_updated = t_now; - else - bgp_damp_info_free (bdi, 0); - - return status; + time_t t_now; + struct bgp_damp_info *bdi; + int status; + + if (!binfo->extra || !((bdi = binfo->extra->damp_info))) + return BGP_DAMP_USED; + + t_now = bgp_clock(); + bgp_info_unset_flag(rn, binfo, BGP_INFO_HISTORY); + + bdi->lastrecord = BGP_RECORD_UPDATE; + bdi->penalty = bgp_damp_decay(t_now - bdi->t_updated, bdi->penalty); + + if (!CHECK_FLAG(bdi->binfo->flags, BGP_INFO_DAMPED) + && (bdi->penalty < damp->suppress_value)) + status = BGP_DAMP_USED; + else if (CHECK_FLAG(bdi->binfo->flags, BGP_INFO_DAMPED) + && (bdi->penalty < damp->reuse_limit)) { + bgp_info_unset_flag(rn, binfo, BGP_INFO_DAMPED); + bgp_reuse_list_delete(bdi); + BGP_DAMP_LIST_ADD(damp, bdi); + bdi->suppress_time = 0; + status = BGP_DAMP_USED; + } else + status = BGP_DAMP_SUPPRESSED; + + if (bdi->penalty > damp->reuse_limit / 2.0) + bdi->t_updated = t_now; + else + bgp_damp_info_free(bdi, 0); + + return status; } /* Remove dampening information and history route. */ -int -bgp_damp_scan (struct bgp_info *binfo, afi_t afi, safi_t safi) +int bgp_damp_scan(struct bgp_info *binfo, afi_t afi, safi_t safi) { - time_t t_now, t_diff; - struct bgp_damp_info *bdi; - - assert (binfo->extra && binfo->extra->damp_info); - - t_now = bgp_clock (); - bdi = binfo->extra->damp_info; - - if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED)) - { - t_diff = t_now - bdi->suppress_time; - - if (t_diff >= damp->max_suppress_time) - { - bgp_info_unset_flag (bdi->rn, binfo, BGP_INFO_DAMPED); - bgp_reuse_list_delete (bdi); - BGP_DAMP_LIST_ADD (damp, bdi); - bdi->penalty = damp->reuse_limit; - bdi->suppress_time = 0; - bdi->t_updated = t_now; - - /* Need to announce UPDATE once this binfo is usable again. */ - if (bdi->lastrecord == BGP_RECORD_UPDATE) - return 1; - else - return 0; - } - } - else - { - t_diff = t_now - bdi->t_updated; - bdi->penalty = bgp_damp_decay (t_diff, bdi->penalty); - - if (bdi->penalty <= damp->reuse_limit / 2.0) - { - /* release the bdi, bdi->binfo. */ - bgp_damp_info_free (bdi, 1); - return 0; - } - else - bdi->t_updated = t_now; - } - return 0; + time_t t_now, t_diff; + struct bgp_damp_info *bdi; + + assert(binfo->extra && binfo->extra->damp_info); + + t_now = bgp_clock(); + bdi = binfo->extra->damp_info; + + if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)) { + t_diff = t_now - bdi->suppress_time; + + if (t_diff >= damp->max_suppress_time) { + bgp_info_unset_flag(bdi->rn, binfo, BGP_INFO_DAMPED); + bgp_reuse_list_delete(bdi); + BGP_DAMP_LIST_ADD(damp, bdi); + bdi->penalty = damp->reuse_limit; + bdi->suppress_time = 0; + bdi->t_updated = t_now; + + /* Need to announce UPDATE once this binfo is usable + * again. */ + if (bdi->lastrecord == BGP_RECORD_UPDATE) + return 1; + else + return 0; + } + } else { + t_diff = t_now - bdi->t_updated; + bdi->penalty = bgp_damp_decay(t_diff, bdi->penalty); + + if (bdi->penalty <= damp->reuse_limit / 2.0) { + /* release the bdi, bdi->binfo. */ + bgp_damp_info_free(bdi, 1); + return 0; + } else + bdi->t_updated = t_now; + } + return 0; } -void -bgp_damp_info_free (struct bgp_damp_info *bdi, int withdraw) +void bgp_damp_info_free(struct bgp_damp_info *bdi, int withdraw) { - struct bgp_info *binfo; + struct bgp_info *binfo; + + if (!bdi) + return; - if (! bdi) - return; + binfo = bdi->binfo; + binfo->extra->damp_info = NULL; - binfo = bdi->binfo; - binfo->extra->damp_info = NULL; + if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)) + bgp_reuse_list_delete(bdi); + else + BGP_DAMP_LIST_DEL(damp, bdi); - if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED)) - bgp_reuse_list_delete (bdi); - else - BGP_DAMP_LIST_DEL (damp, bdi); + bgp_info_unset_flag(bdi->rn, binfo, BGP_INFO_HISTORY | BGP_INFO_DAMPED); - bgp_info_unset_flag (bdi->rn, binfo, BGP_INFO_HISTORY|BGP_INFO_DAMPED); + if (bdi->lastrecord == BGP_RECORD_WITHDRAW && withdraw) + bgp_info_delete(bdi->rn, binfo); - if (bdi->lastrecord == BGP_RECORD_WITHDRAW && withdraw) - bgp_info_delete (bdi->rn, binfo); - - XFREE (MTYPE_BGP_DAMP_INFO, bdi); + XFREE(MTYPE_BGP_DAMP_INFO, bdi); } -static void -bgp_damp_parameter_set (int hlife, int reuse, int sup, int maxsup) +static void bgp_damp_parameter_set(int hlife, int reuse, int sup, int maxsup) { - double reuse_max_ratio; - unsigned int i; - double j; - - damp->suppress_value = sup; - damp->half_life = hlife; - damp->reuse_limit = reuse; - damp->max_suppress_time = maxsup; - - /* Initialize params per bgp_damp_config. */ - damp->reuse_index_size = REUSE_ARRAY_SIZE; - - damp->ceiling = (int)(damp->reuse_limit * (pow(2, (double)damp->max_suppress_time/damp->half_life))); - - /* Decay-array computations */ - damp->decay_array_size = ceil ((double) damp->max_suppress_time / DELTA_T); - damp->decay_array = XMALLOC (MTYPE_BGP_DAMP_ARRAY, - sizeof(double) * (damp->decay_array_size)); - damp->decay_array[0] = 1.0; - damp->decay_array[1] = exp ((1.0/((double)damp->half_life/DELTA_T)) * log(0.5)); - - /* Calculate decay values for all possible times */ - for (i = 2; i < damp->decay_array_size; i++) - damp->decay_array[i] = damp->decay_array[i-1] * damp->decay_array[1]; - - /* Reuse-list computations */ - i = ceil ((double)damp->max_suppress_time / DELTA_REUSE) + 1; - if (i > REUSE_LIST_SIZE || i == 0) - i = REUSE_LIST_SIZE; - damp->reuse_list_size = i; - - damp->reuse_list = XCALLOC (MTYPE_BGP_DAMP_ARRAY, - damp->reuse_list_size - * sizeof (struct bgp_reuse_node *)); - - /* Reuse-array computations */ - damp->reuse_index = XCALLOC (MTYPE_BGP_DAMP_ARRAY, - sizeof(int) * damp->reuse_index_size); - - reuse_max_ratio = (double)damp->ceiling/damp->reuse_limit; - j = (exp((double)damp->max_suppress_time/damp->half_life) * log10(2.0)); - if ( reuse_max_ratio > j && j != 0 ) - reuse_max_ratio = j; - - damp->scale_factor = (double)damp->reuse_index_size/(reuse_max_ratio - 1); - - for (i = 0; i < damp->reuse_index_size; i++) - { - damp->reuse_index[i] = - (int)(((double)damp->half_life / DELTA_REUSE) - * log10 (1.0 / (damp->reuse_limit * ( 1.0 + ((double)i/damp->scale_factor)))) / log10(0.5)); - } + double reuse_max_ratio; + unsigned int i; + double j; + + damp->suppress_value = sup; + damp->half_life = hlife; + damp->reuse_limit = reuse; + damp->max_suppress_time = maxsup; + + /* Initialize params per bgp_damp_config. */ + damp->reuse_index_size = REUSE_ARRAY_SIZE; + + damp->ceiling = + (int)(damp->reuse_limit * (pow(2, + (double)damp->max_suppress_time + / damp->half_life))); + + /* Decay-array computations */ + damp->decay_array_size = + ceil((double)damp->max_suppress_time / DELTA_T); + damp->decay_array = XMALLOC(MTYPE_BGP_DAMP_ARRAY, + sizeof(double) * (damp->decay_array_size)); + damp->decay_array[0] = 1.0; + damp->decay_array[1] = + exp((1.0 / ((double)damp->half_life / DELTA_T)) * log(0.5)); + + /* Calculate decay values for all possible times */ + for (i = 2; i < damp->decay_array_size; i++) + damp->decay_array[i] = + damp->decay_array[i - 1] * damp->decay_array[1]; + + /* Reuse-list computations */ + i = ceil((double)damp->max_suppress_time / DELTA_REUSE) + 1; + if (i > REUSE_LIST_SIZE || i == 0) + i = REUSE_LIST_SIZE; + damp->reuse_list_size = i; + + damp->reuse_list = XCALLOC(MTYPE_BGP_DAMP_ARRAY, + damp->reuse_list_size + * sizeof(struct bgp_reuse_node *)); + + /* Reuse-array computations */ + damp->reuse_index = XCALLOC(MTYPE_BGP_DAMP_ARRAY, + sizeof(int) * damp->reuse_index_size); + + reuse_max_ratio = (double)damp->ceiling / damp->reuse_limit; + j = (exp((double)damp->max_suppress_time / damp->half_life) + * log10(2.0)); + if (reuse_max_ratio > j && j != 0) + reuse_max_ratio = j; + + damp->scale_factor = + (double)damp->reuse_index_size / (reuse_max_ratio - 1); + + for (i = 0; i < damp->reuse_index_size; i++) { + damp->reuse_index[i] = + (int)(((double)damp->half_life / DELTA_REUSE) + * log10(1.0 / (damp->reuse_limit + * (1.0 + ((double)i + / damp->scale_factor)))) + / log10(0.5)); + } } -int -bgp_damp_enable (struct bgp *bgp, afi_t afi, safi_t safi, time_t half, - unsigned int reuse, unsigned int suppress, time_t max) +int bgp_damp_enable(struct bgp *bgp, afi_t afi, safi_t safi, time_t half, + unsigned int reuse, unsigned int suppress, time_t max) { - if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) - { - if (damp->half_life == half - && damp->reuse_limit == reuse - && damp->suppress_value == suppress - && damp->max_suppress_time == max) - return 0; - bgp_damp_disable (bgp, afi, safi); - } + if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) { + if (damp->half_life == half && damp->reuse_limit == reuse + && damp->suppress_value == suppress + && damp->max_suppress_time == max) + return 0; + bgp_damp_disable(bgp, afi, safi); + } - SET_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING); - bgp_damp_parameter_set (half, reuse, suppress, max); + SET_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING); + bgp_damp_parameter_set(half, reuse, suppress, max); - /* Register reuse timer. */ - thread_add_timer(bm->master, bgp_reuse_timer, NULL, DELTA_REUSE, - &damp->t_reuse); + /* Register reuse timer. */ + thread_add_timer(bm->master, bgp_reuse_timer, NULL, DELTA_REUSE, + &damp->t_reuse); - return 0; + return 0; } -static void -bgp_damp_config_clean (struct bgp_damp_config *damp) +static void bgp_damp_config_clean(struct bgp_damp_config *damp) { - /* Free decay array */ - XFREE (MTYPE_BGP_DAMP_ARRAY, damp->decay_array); + /* Free decay array */ + XFREE(MTYPE_BGP_DAMP_ARRAY, damp->decay_array); - /* Free reuse index array */ - XFREE (MTYPE_BGP_DAMP_ARRAY, damp->reuse_index); + /* Free reuse index array */ + XFREE(MTYPE_BGP_DAMP_ARRAY, damp->reuse_index); - /* Free reuse list array. */ - XFREE (MTYPE_BGP_DAMP_ARRAY, damp->reuse_list); + /* Free reuse list array. */ + XFREE(MTYPE_BGP_DAMP_ARRAY, damp->reuse_list); } /* Clean all the bgp_damp_info stored in reuse_list. */ -void -bgp_damp_info_clean (void) +void bgp_damp_info_clean(void) { - unsigned int i; - struct bgp_damp_info *bdi, *next; + unsigned int i; + struct bgp_damp_info *bdi, *next; - damp->reuse_offset = 0; + damp->reuse_offset = 0; - for (i = 0; i < damp->reuse_list_size; i++) - { - if (! damp->reuse_list[i]) - continue; + for (i = 0; i < damp->reuse_list_size; i++) { + if (!damp->reuse_list[i]) + continue; - for (bdi = damp->reuse_list[i]; bdi; bdi = next) - { - next = bdi->next; - bgp_damp_info_free (bdi, 1); + for (bdi = damp->reuse_list[i]; bdi; bdi = next) { + next = bdi->next; + bgp_damp_info_free(bdi, 1); + } + damp->reuse_list[i] = NULL; } - damp->reuse_list[i] = NULL; - } - - for (bdi = damp->no_reuse_list; bdi; bdi = next) - { - next = bdi->next; - bgp_damp_info_free (bdi, 1); - } - damp->no_reuse_list = NULL; + + for (bdi = damp->no_reuse_list; bdi; bdi = next) { + next = bdi->next; + bgp_damp_info_free(bdi, 1); + } + damp->no_reuse_list = NULL; } -int -bgp_damp_disable (struct bgp *bgp, afi_t afi, safi_t safi) +int bgp_damp_disable(struct bgp *bgp, afi_t afi, safi_t safi) { - /* If it wasn't enabled, there's nothing to do. */ - if (! CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) - return 0; + /* If it wasn't enabled, there's nothing to do. */ + if (!CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) + return 0; - /* Cancel reuse thread. */ - if (damp->t_reuse ) - thread_cancel (damp->t_reuse); - damp->t_reuse = NULL; + /* Cancel reuse thread. */ + if (damp->t_reuse) + thread_cancel(damp->t_reuse); + damp->t_reuse = NULL; - /* Clean BGP dampening information. */ - bgp_damp_info_clean (); + /* Clean BGP dampening information. */ + bgp_damp_info_clean(); - /* Clear configuration */ - bgp_damp_config_clean (&bgp_damp_cfg); + /* Clear configuration */ + bgp_damp_config_clean(&bgp_damp_cfg); - UNSET_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING); - return 0; + UNSET_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING); + return 0; } -void -bgp_config_write_damp (struct vty *vty) +void bgp_config_write_damp(struct vty *vty) { - if (bgp_damp_cfg.half_life == DEFAULT_HALF_LIFE*60 - && bgp_damp_cfg.reuse_limit == DEFAULT_REUSE - && bgp_damp_cfg.suppress_value == DEFAULT_SUPPRESS - && bgp_damp_cfg.max_suppress_time == bgp_damp_cfg.half_life*4) - vty_out (vty, " bgp dampening\n"); - else if (bgp_damp_cfg.half_life != DEFAULT_HALF_LIFE*60 - && bgp_damp_cfg.reuse_limit == DEFAULT_REUSE - && bgp_damp_cfg.suppress_value == DEFAULT_SUPPRESS - && bgp_damp_cfg.max_suppress_time == bgp_damp_cfg.half_life*4) - vty_out (vty, " bgp dampening %lld\n", - bgp_damp_cfg.half_life / 60LL); - else - vty_out (vty, " bgp dampening %lld %d %d %lld\n", - bgp_damp_cfg.half_life/60LL, - bgp_damp_cfg.reuse_limit, - bgp_damp_cfg.suppress_value, - bgp_damp_cfg.max_suppress_time / 60LL); + if (bgp_damp_cfg.half_life == DEFAULT_HALF_LIFE * 60 + && bgp_damp_cfg.reuse_limit == DEFAULT_REUSE + && bgp_damp_cfg.suppress_value == DEFAULT_SUPPRESS + && bgp_damp_cfg.max_suppress_time == bgp_damp_cfg.half_life * 4) + vty_out(vty, " bgp dampening\n"); + else if (bgp_damp_cfg.half_life != DEFAULT_HALF_LIFE * 60 + && bgp_damp_cfg.reuse_limit == DEFAULT_REUSE + && bgp_damp_cfg.suppress_value == DEFAULT_SUPPRESS + && bgp_damp_cfg.max_suppress_time + == bgp_damp_cfg.half_life * 4) + vty_out(vty, " bgp dampening %lld\n", + bgp_damp_cfg.half_life / 60LL); + else + vty_out(vty, " bgp dampening %lld %d %d %lld\n", + bgp_damp_cfg.half_life / 60LL, bgp_damp_cfg.reuse_limit, + bgp_damp_cfg.suppress_value, + bgp_damp_cfg.max_suppress_time / 60LL); } -static const char * -bgp_get_reuse_time (unsigned int penalty, char *buf, size_t len, u_char use_json, json_object *json) +static const char *bgp_get_reuse_time(unsigned int penalty, char *buf, + size_t len, u_char use_json, + json_object *json) { - time_t reuse_time = 0; - struct tm *tm = NULL; - int time_store = 0; + time_t reuse_time = 0; + struct tm *tm = NULL; + int time_store = 0; - if (penalty > damp->reuse_limit) - { - reuse_time = (int) (DELTA_T * ((log((double)damp->reuse_limit/penalty))/(log(damp->decay_array[1])))); + if (penalty > damp->reuse_limit) { + reuse_time = (int)(DELTA_T + * ((log((double)damp->reuse_limit / penalty)) + / (log(damp->decay_array[1])))); - if (reuse_time > damp->max_suppress_time) - reuse_time = damp->max_suppress_time; + if (reuse_time > damp->max_suppress_time) + reuse_time = damp->max_suppress_time; - tm = gmtime (&reuse_time); - } - else - reuse_time = 0; + tm = gmtime(&reuse_time); + } else + reuse_time = 0; - /* Making formatted timer strings. */ +/* Making formatted timer strings. */ #define ONE_DAY_SECOND 60*60*24 #define ONE_WEEK_SECOND 60*60*24*7 - if (reuse_time == 0) - { - if (use_json) - json_object_int_add(json, "reuseTimerMsecs", 0); - else - snprintf (buf, len, "00:00:00"); - } - else if (reuse_time < ONE_DAY_SECOND) - { - if (use_json) - { - time_store = (3600000 * tm->tm_hour) + (60000 * tm->tm_min) + (1000 * tm->tm_sec); - json_object_int_add(json, "reuseTimerMsecs", time_store); - } - else - snprintf (buf, len, "%02d:%02d:%02d", - tm->tm_hour, tm->tm_min, tm->tm_sec); - } - else if (reuse_time < ONE_WEEK_SECOND) - { - if (use_json) - { - time_store = (86400000 * tm->tm_yday) + (3600000 * tm->tm_hour) + (60000 * tm->tm_min) + (1000 * tm->tm_sec); - json_object_int_add(json, "reuseTimerMsecs", time_store); - } - else - snprintf (buf, len, "%dd%02dh%02dm", - tm->tm_yday, tm->tm_hour, tm->tm_min); - } - else - { - if (use_json) - { - time_store = (604800000 * tm->tm_yday/7) + (86400000 * (tm->tm_yday - ((tm->tm_yday/7) * 7))) + (3600000 * tm->tm_hour) + (60000 * tm->tm_min) + (1000 * tm->tm_sec); - json_object_int_add(json, "reuseTimerMsecs", time_store); - } - else - snprintf (buf, len, "%02dw%dd%02dh", - tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); - } - - return buf; + if (reuse_time == 0) { + if (use_json) + json_object_int_add(json, "reuseTimerMsecs", 0); + else + snprintf(buf, len, "00:00:00"); + } else if (reuse_time < ONE_DAY_SECOND) { + if (use_json) { + time_store = (3600000 * tm->tm_hour) + + (60000 * tm->tm_min) + + (1000 * tm->tm_sec); + json_object_int_add(json, "reuseTimerMsecs", + time_store); + } else + snprintf(buf, len, "%02d:%02d:%02d", tm->tm_hour, + tm->tm_min, tm->tm_sec); + } else if (reuse_time < ONE_WEEK_SECOND) { + if (use_json) { + time_store = (86400000 * tm->tm_yday) + + (3600000 * tm->tm_hour) + + (60000 * tm->tm_min) + + (1000 * tm->tm_sec); + json_object_int_add(json, "reuseTimerMsecs", + time_store); + } else + snprintf(buf, len, "%dd%02dh%02dm", tm->tm_yday, + tm->tm_hour, tm->tm_min); + } else { + if (use_json) { + time_store = + (604800000 * tm->tm_yday / 7) + + (86400000 + * (tm->tm_yday - ((tm->tm_yday / 7) * 7))) + + (3600000 * tm->tm_hour) + (60000 * tm->tm_min) + + (1000 * tm->tm_sec); + json_object_int_add(json, "reuseTimerMsecs", + time_store); + } else + snprintf(buf, len, "%02dw%dd%02dh", tm->tm_yday / 7, + tm->tm_yday - ((tm->tm_yday / 7) * 7), + tm->tm_hour); + } + + return buf; } - -void -bgp_damp_info_vty (struct vty *vty, struct bgp_info *binfo, - json_object *json_path) + +void bgp_damp_info_vty(struct vty *vty, struct bgp_info *binfo, + json_object *json_path) { - struct bgp_damp_info *bdi; - time_t t_now, t_diff; - char timebuf[BGP_UPTIME_LEN]; - int penalty; - - if (!binfo->extra) - return; - - /* BGP dampening information. */ - bdi = binfo->extra->damp_info; - - /* If dampening is not enabled or there is no dampening information, - return immediately. */ - if (! damp || ! bdi) - return; - - /* Calculate new penalty. */ - t_now = bgp_clock (); - t_diff = t_now - bdi->t_updated; - penalty = bgp_damp_decay (t_diff, bdi->penalty); - - if (json_path) - { - json_object_int_add(json_path, "dampeningPenalty", penalty); - json_object_int_add(json_path, "dampeningFlapCount", bdi->flap); - peer_uptime (bdi->start_time, timebuf, BGP_UPTIME_LEN, 1, json_path); - - if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED) - && ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY)) - bgp_get_reuse_time (penalty, timebuf, BGP_UPTIME_LEN, 1, json_path); - } - else - { - vty_out (vty, " Dampinfo: penalty %d, flapped %d times in %s", - penalty, bdi->flap, - peer_uptime (bdi->start_time, timebuf, BGP_UPTIME_LEN, 0, json_path)); - - if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED) - && ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY)) - vty_out (vty, ", reuse in %s", - bgp_get_reuse_time (penalty, timebuf, BGP_UPTIME_LEN, 0, json_path)); - - vty_out (vty, "\n"); - } + struct bgp_damp_info *bdi; + time_t t_now, t_diff; + char timebuf[BGP_UPTIME_LEN]; + int penalty; + + if (!binfo->extra) + return; + + /* BGP dampening information. */ + bdi = binfo->extra->damp_info; + + /* If dampening is not enabled or there is no dampening information, + return immediately. */ + if (!damp || !bdi) + return; + + /* Calculate new penalty. */ + t_now = bgp_clock(); + t_diff = t_now - bdi->t_updated; + penalty = bgp_damp_decay(t_diff, bdi->penalty); + + if (json_path) { + json_object_int_add(json_path, "dampeningPenalty", penalty); + json_object_int_add(json_path, "dampeningFlapCount", bdi->flap); + peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, 1, + json_path); + + if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED) + && !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY)) + bgp_get_reuse_time(penalty, timebuf, BGP_UPTIME_LEN, 1, + json_path); + } else { + vty_out(vty, + " Dampinfo: penalty %d, flapped %d times in %s", + penalty, bdi->flap, + peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, 0, + json_path)); + + if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED) + && !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY)) + vty_out(vty, ", reuse in %s", + bgp_get_reuse_time(penalty, timebuf, + BGP_UPTIME_LEN, 0, + json_path)); + + vty_out(vty, "\n"); + } } -const char * -bgp_damp_reuse_time_vty (struct vty *vty, struct bgp_info *binfo, - char *timebuf, size_t len, u_char use_json, json_object *json) +const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_info *binfo, + char *timebuf, size_t len, u_char use_json, + json_object *json) { - struct bgp_damp_info *bdi; - time_t t_now, t_diff; - int penalty; - - if (!binfo->extra) - return NULL; - - /* BGP dampening information. */ - bdi = binfo->extra->damp_info; - - /* If dampening is not enabled or there is no dampening information, - return immediately. */ - if (! damp || ! bdi) - return NULL; - - /* Calculate new penalty. */ - t_now = bgp_clock (); - t_diff = t_now - bdi->t_updated; - penalty = bgp_damp_decay (t_diff, bdi->penalty); - - return bgp_get_reuse_time (penalty, timebuf, len, use_json, json); + struct bgp_damp_info *bdi; + time_t t_now, t_diff; + int penalty; + + if (!binfo->extra) + return NULL; + + /* BGP dampening information. */ + bdi = binfo->extra->damp_info; + + /* If dampening is not enabled or there is no dampening information, + return immediately. */ + if (!damp || !bdi) + return NULL; + + /* Calculate new penalty. */ + t_now = bgp_clock(); + t_diff = t_now - bdi->t_updated; + penalty = bgp_damp_decay(t_diff, bdi->penalty); + + return bgp_get_reuse_time(penalty, timebuf, len, use_json, json); } -int -bgp_show_dampening_parameters (struct vty *vty, afi_t afi, safi_t safi) +int bgp_show_dampening_parameters(struct vty *vty, afi_t afi, safi_t safi) { - struct bgp *bgp; - bgp = bgp_get_default(); - - if (bgp == NULL) - { - vty_out (vty, "No BGP process is configured\n"); - return CMD_WARNING; - } - - if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) - { - vty_out (vty, "Half-life time: %lld min\n", - (long long)damp->half_life / 60); - vty_out (vty, "Reuse penalty: %d\n", - damp->reuse_limit); - vty_out (vty, "Suppress penalty: %d\n", - damp->suppress_value); - vty_out (vty, "Max suppress time: %lld min\n", - (long long)damp->max_suppress_time / 60); - vty_out (vty, "Max supress penalty: %u\n", - damp->ceiling); - vty_out (vty, "\n"); - } - else - vty_out (vty, "dampening not enabled for %s\n", - afi == AFI_IP ? "IPv4" : "IPv6"); - - return CMD_SUCCESS; + struct bgp *bgp; + bgp = bgp_get_default(); + + if (bgp == NULL) { + vty_out(vty, "No BGP process is configured\n"); + return CMD_WARNING; + } + + if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) { + vty_out(vty, "Half-life time: %lld min\n", + (long long)damp->half_life / 60); + vty_out(vty, "Reuse penalty: %d\n", damp->reuse_limit); + vty_out(vty, "Suppress penalty: %d\n", damp->suppress_value); + vty_out(vty, "Max suppress time: %lld min\n", + (long long)damp->max_suppress_time / 60); + vty_out(vty, "Max supress penalty: %u\n", damp->ceiling); + vty_out(vty, "\n"); + } else + vty_out(vty, "dampening not enabled for %s\n", + afi == AFI_IP ? "IPv4" : "IPv6"); + + return CMD_SUCCESS; } |