summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_damp.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_damp.c')
-rw-r--r--bgpd/bgp_damp.c134
1 files changed, 75 insertions, 59 deletions
diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c
index e21131ef..52a93eb7 100644
--- a/bgpd/bgp_damp.c
+++ b/bgpd/bgp_damp.c
@@ -31,7 +31,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#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 */
@@ -40,9 +40,25 @@ static struct bgp_damp_config *damp = &bgp_damp_cfg;
/* Utility macro to add and delete BGP dampening information to no
used list. */
-#define BGP_DAMP_LIST_ADD(N,A) BGP_INFO_ADD(N,A,no_reuse_list)
-#define BGP_DAMP_LIST_DEL(N,A) BGP_INFO_DEL(N,A,no_reuse_list)
-
+#define BGP_DAMP_LIST_ADD(N,A) \
+ do { \
+ (A)->prev = NULL; \
+ (A)->next = (N)->no_reuse_list; \
+ if ((N)->no_reuse_list) \
+ (N)->no_reuse_list->prev = (A); \
+ (N)->no_reuse_list = (A); \
+ } while (0)
+
+#define BGP_DAMP_LIST_DEL(N,A) \
+ do { \
+ if ((A)->next) \
+ (A)->next->prev = (A)->prev; \
+ if ((A)->prev) \
+ (A)->prev->next = (A)->next; \
+ else \
+ (N)->no_reuse_list = (A)->next; \
+ } while (0)
+
/* Calculate reuse list index by penalty value. */
static int
bgp_reuse_index (int penalty)
@@ -51,17 +67,17 @@ bgp_reuse_index (int penalty)
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;
index = damp->reuse_index[i] - damp->reuse_index[0];
- return (damp->reuse_offset + index) % damp->reuse_list_size;
+ return (damp->reuse_offset + index) % damp->reuse_list_size;
}
/* Add BGP dampening information to reuse list. */
-static void
+static void
bgp_reuse_list_add (struct bgp_damp_info *bdi)
{
int index;
@@ -85,10 +101,10 @@ bgp_reuse_list_delete (struct bgp_damp_info *bdi)
bdi->prev->next = bdi->next;
else
damp->reuse_list[bdi->index] = bdi->next;
-}
-
+}
+
/* Return decayed penalty value. */
-int
+int
bgp_damp_decay (time_t tdiff, int penalty)
{
unsigned int i;
@@ -96,8 +112,8 @@ bgp_damp_decay (time_t tdiff, int penalty)
i = (int) ((double) tdiff / DELTA_T);
if (i == 0)
- return penalty;
-
+ return penalty;
+
if (i >= damp->decay_array_size)
return 0;
@@ -112,7 +128,7 @@ 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;
damp->t_reuse =
thread_add_timer (master, bgp_reuse_timer, NULL, DELTA_REUSE);
@@ -132,14 +148,14 @@ bgp_reuse_timer (struct thread *t)
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);
+ bdi->penalty = bgp_damp_decay (t_diff, bdi->penalty);
/* Set t-updated = t-now. */
bdi->t_updated = t_now;
@@ -155,7 +171,7 @@ bgp_reuse_timer (struct thread *t)
{
bgp_info_unset_flag (bdi->rn, bdi->binfo, BGP_INFO_HISTORY);
bgp_aggregate_increment (bgp, &bdi->rn->p, bdi->binfo,
- bdi->afi, bdi->safi);
+ bdi->afi, bdi->safi);
bgp_process (bgp, bdi->rn, bdi->afi, bdi->safi);
}
@@ -180,13 +196,13 @@ bgp_damp_withdraw (struct bgp_info *binfo, struct bgp_node *rn,
time_t t_now;
struct bgp_damp_info *bdi = NULL;
double last_penalty = 0;
-
+
t_now = time (NULL);
/* Processing Unreachable Messages. */
if (binfo->extra)
bdi = binfo->extra->damp_info;
-
+
if (bdi == NULL)
{
/* If there is no previous stability history. */
@@ -214,8 +230,8 @@ bgp_damp_withdraw (struct bgp_info *binfo, struct bgp_node *rn,
last_penalty = bdi->penalty;
/* 1. Set t-diff = t-now - t-updated. */
- bdi->penalty =
- (bgp_damp_decay (t_now - bdi->t_updated, bdi->penalty)
+ bdi->penalty =
+ (bgp_damp_decay (t_now - bdi->t_updated, bdi->penalty)
+ (attr_change ? DEFAULT_PENALTY / 2 : DEFAULT_PENALTY));
if (bdi->penalty > damp->ceiling)
@@ -223,9 +239,9 @@ bgp_damp_withdraw (struct bgp_info *binfo, struct bgp_node *rn,
bdi->flap++;
}
-
+
assert ((rn == bdi->rn) && (binfo == bdi->binfo));
-
+
bdi->lastrecord = BGP_RECORD_WITHDRAW;
bdi->t_updated = t_now;
@@ -235,13 +251,13 @@ bgp_damp_withdraw (struct bgp_info *binfo, struct bgp_node *rn,
/* 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 decay rate isn't equal to 0, reinsert brn. */
if (bdi->penalty != last_penalty)
{
bgp_reuse_list_delete (bdi);
- bgp_reuse_list_add (bdi);
+ bgp_reuse_list_add (bdi);
}
- return BGP_DAMP_SUPPRESSED;
+ return BGP_DAMP_SUPPRESSED;
}
/* If not suppressed before, do annonunce this withdraw and
@@ -258,7 +274,7 @@ bgp_damp_withdraw (struct bgp_info *binfo, struct bgp_node *rn,
}
int
-bgp_damp_update (struct bgp_info *binfo, struct bgp_node *rn,
+bgp_damp_update (struct bgp_info *binfo, struct bgp_node *rn,
afi_t afi, safi_t safi)
{
time_t t_now;
@@ -287,28 +303,28 @@ bgp_damp_update (struct bgp_info *binfo, struct bgp_node *rn,
status = BGP_DAMP_USED;
}
else
- status = BGP_DAMP_SUPPRESSED;
+ 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
+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 = time (NULL);
bdi = binfo->extra->damp_info;
-
+
if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
{
t_diff = t_now - bdi->suppress_time;
@@ -321,7 +337,7 @@ bgp_damp_scan (struct bgp_info *binfo, afi_t afi, safi_t safi)
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;
@@ -336,13 +352,13 @@ bgp_damp_scan (struct bgp_info *binfo, afi_t afi, safi_t safi)
if (bdi->penalty <= damp->reuse_limit / 2.0)
{
- /* release the bdi, bdi->binfo. */
+ /* release the bdi, bdi->binfo. */
bgp_damp_info_free (bdi, 1);
return 0;
- }
+ }
else
bdi->t_updated = t_now;
- }
+ }
return 0;
}
@@ -366,7 +382,7 @@ bgp_damp_info_free (struct bgp_damp_info *bdi, int withdraw)
if (bdi->lastrecord == BGP_RECORD_WITHDRAW && withdraw)
bgp_info_delete (bdi->rn, binfo);
-
+
XFREE (MTYPE_BGP_DAMP_INFO, bdi);
}
@@ -376,7 +392,7 @@ 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;
@@ -385,7 +401,7 @@ bgp_damp_parameter_set (int hlife, int reuse, int sup, int 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)));
+ 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);
@@ -397,21 +413,21 @@ bgp_damp_parameter_set (int hlife, int reuse, int sup, int maxsup)
/* 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_size = i;
- damp->reuse_list = XCALLOC (MTYPE_BGP_DAMP_ARRAY,
- damp->reuse_list_size
+ damp->reuse_list = XCALLOC (MTYPE_BGP_DAMP_ARRAY,
+ damp->reuse_list_size
* sizeof (struct bgp_reuse_node *));
- memset (damp->reuse_list, 0x00,
- damp->reuse_list_size * sizeof (struct bgp_reuse_node *));
+ memset (damp->reuse_list, 0x00,
+ damp->reuse_list_size * sizeof (struct bgp_reuse_node *));
/* Reuse-array computations */
- damp->reuse_index = XMALLOC (MTYPE_BGP_DAMP_ARRAY,
+ damp->reuse_index = XMALLOC (MTYPE_BGP_DAMP_ARRAY,
sizeof(int) * damp->reuse_index_size);
memset (damp->reuse_index, 0x00,
damp->reuse_list_size * sizeof (int));
@@ -425,7 +441,7 @@ bgp_damp_parameter_set (int hlife, int reuse, int sup, int maxsup)
for (i = 0; i < damp->reuse_index_size; i++)
{
- damp->reuse_index[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));
}
@@ -450,7 +466,7 @@ bgp_damp_enable (struct bgp *bgp, afi_t afi, safi_t safi, time_t half,
/* Register reuse timer. */
if (! damp->t_reuse)
- damp->t_reuse =
+ damp->t_reuse =
thread_add_timer (master, bgp_reuse_timer, NULL, DELTA_REUSE);
return 0;
@@ -549,14 +565,14 @@ bgp_get_reuse_time (unsigned int penalty, char *buf, size_t len)
if (penalty > damp->reuse_limit)
{
- reuse_time = (int) (DELTA_T * ((log((double)damp->reuse_limit/penalty))/(log(damp->decay_array[1]))));
+ 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;
tm = gmtime (&reuse_time);
}
- else
+ else
reuse_time = 0;
/* Making formatted timer strings. */
@@ -565,20 +581,20 @@ bgp_get_reuse_time (unsigned int penalty, char *buf, size_t len)
if (reuse_time == 0)
snprintf (buf, len, "00:00:00");
else if (reuse_time < ONE_DAY_SECOND)
- snprintf (buf, len, "%02d:%02d:%02d",
+ snprintf (buf, len, "%02d:%02d:%02d",
tm->tm_hour, tm->tm_min, tm->tm_sec);
else if (reuse_time < ONE_WEEK_SECOND)
- snprintf (buf, len, "%dd%02dh%02dm",
+ snprintf (buf, len, "%dd%02dh%02dm",
tm->tm_yday, tm->tm_hour, tm->tm_min);
else
- snprintf (buf, len, "%02dw%dd%02dh",
- tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
+ 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)
+bgp_damp_info_vty (struct vty *vty, struct bgp_info *binfo)
{
struct bgp_damp_info *bdi;
time_t t_now, t_diff;
@@ -587,7 +603,7 @@ bgp_damp_info_vty (struct vty *vty, struct bgp_info *binfo)
if (!binfo->extra)
return;
-
+
/* BGP dampening information. */
bdi = binfo->extra->damp_info;
@@ -620,10 +636,10 @@ bgp_damp_reuse_time_vty (struct vty *vty, struct bgp_info *binfo,
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;