summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_damp.c
diff options
context:
space:
mode:
authorDonatas Abraitis <donatas.abraitis@gmail.com>2019-11-10 19:13:20 +0100
committerDonatas Abraitis <donatas.abraitis@gmail.com>2019-11-11 08:52:40 +0100
commita935f597fcfa52bce4581439ae6b3399a86637db (patch)
tree16a75113883f4894b5c9e6dd4e0e89bac4e1561a /bgpd/bgp_damp.c
parentMerge pull request #5298 from donaldsharp/bgp_prefix_rpki (diff)
downloadfrr-a935f597fcfa52bce4581439ae6b3399a86637db.tar.xz
frr-a935f597fcfa52bce4581439ae6b3399a86637db.zip
bgpd: Rework BGP dampening to be per AFI/SAFI
Before we had: ! router bgp 65031 bgp dampening 1 2 3 4 ! exit2-debian-9(config)# router bgp 65031 exit2-debian-9(config-router)# address-family ipv4 multicast exit2-debian-9(config-router-af)# bgp dampening 5 6 7 8 exit2-debian-9(config-router-af)# end exit2-debian-9# show running-config ! router bgp 65031 bgp dampening 1 2 3 4 ! After fix: ! router bgp 65031 neighbor 192.168.1.2 remote-as 100 ! address-family ipv4 unicast bgp dampening 1 2 3 4 exit-address-family ! address-family ipv4 multicast bgp dampening 5 6 7 8 exit-address-family ! exit2-debian-9# show ip bgp ipv4 unicast dampening parameters Half-life time: 1 min Reuse penalty: 2 Suppress penalty: 3 Max suppress time: 4 min Max suppress penalty: 32 exit2-debian-9# show ip bgp ipv4 multicast dampening parameters Half-life time: 5 min Reuse penalty: 6 Suppress penalty: 7 Max suppress time: 8 min Max suppress penalty: 18 Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
Diffstat (limited to 'bgpd/bgp_damp.c')
-rw-r--r--bgpd/bgp_damp.c385
1 files changed, 181 insertions, 204 deletions
diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c
index cf085e46f..b0fee079d 100644
--- a/bgpd/bgp_damp.c
+++ b/bgpd/bgp_damp.c
@@ -37,8 +37,7 @@
#include "bgpd/bgp_advertise.h"
/* Global variable to access damping configuration */
-struct bgp_damp_config bgp_damp_cfg;
-static struct bgp_damp_config *damp = &bgp_damp_cfg;
+static struct bgp_damp_config damp[AFI_MAX][SAFI_MAX];
/* Utility macro to add and delete BGP dampening information to no
used list. */
@@ -46,49 +45,51 @@ static struct bgp_damp_config *damp = &bgp_damp_cfg;
#define BGP_DAMP_LIST_DEL(N, A) BGP_PATH_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, struct bgp_damp_config *bdc)
{
unsigned int i;
int index;
- i = (int)(((double)penalty / damp->reuse_limit - 1.0)
- * damp->scale_factor);
+ i = (int)(((double)penalty / bdc->reuse_limit - 1.0)
+ * bdc->scale_factor);
- if (i >= damp->reuse_index_size)
- i = damp->reuse_index_size - 1;
+ if (i >= bdc->reuse_index_size)
+ i = bdc->reuse_index_size - 1;
- index = damp->reuse_index[i] - damp->reuse_index[0];
+ index = bdc->reuse_index[i] - bdc->reuse_index[0];
- return (damp->reuse_offset + index) % damp->reuse_list_size;
+ return (bdc->reuse_offset + index) % bdc->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,
+ struct bgp_damp_config *bdc)
{
int index;
- index = bdi->index = bgp_reuse_index(bdi->penalty);
+ index = bdi->index = bgp_reuse_index(bdi->penalty, bdc);
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->next = bdc->reuse_list[index];
+ if (bdc->reuse_list[index])
+ bdc->reuse_list[index]->prev = bdi;
+ bdc->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,
+ struct bgp_damp_config *bdc)
{
if (bdi->next)
bdi->next->prev = bdi->prev;
if (bdi->prev)
bdi->prev->next = bdi->next;
else
- damp->reuse_list[bdi->index] = bdi->next;
+ bdc->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, struct bgp_damp_config *bdc)
{
unsigned int i;
@@ -97,10 +98,10 @@ int bgp_damp_decay(time_t tdiff, int penalty)
if (i == 0)
return penalty;
- if (i >= damp->decay_array_size)
+ if (i >= bdc->decay_array_size)
return 0;
- return (int)(penalty * damp->decay_array[i]);
+ return (int)(penalty * bdc->decay_array[i]);
}
/* Handler of reuse timer event. Each route in the current reuse-list
@@ -111,20 +112,22 @@ static int bgp_reuse_timer(struct thread *t)
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);
+ struct bgp_damp_config *bdc = THREAD_ARG(t);
+
+ bdc->t_reuse = NULL;
+ thread_add_timer(bm->master, bgp_reuse_timer, bdc, DELTA_REUSE,
+ &bdc->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;
+ bdi = bdc->reuse_list[bdc->reuse_offset];
+ bdc->reuse_list[bdc->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;
+ bdc->reuse_offset = (bdc->reuse_offset + 1) % bdc->reuse_list_size;
/* 3. if ( the saved list head pointer is non-empty ) */
for (; bdi; bdi = next) {
@@ -137,13 +140,13 @@ static int bgp_reuse_timer(struct thread *t)
/* 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, bdc);
/* Set t-updated = t-now. */
bdi->t_updated = t_now;
/* if (figure-of-merit < reuse). */
- if (bdi->penalty < damp->reuse_limit) {
+ if (bdi->penalty < bdc->reuse_limit) {
/* Reuse the route. */
bgp_path_info_unset_flag(bdi->rn, bdi->path,
BGP_PATH_DAMPED);
@@ -158,14 +161,14 @@ static int bgp_reuse_timer(struct thread *t)
bgp_process(bgp, bdi->rn, bdi->afi, bdi->safi);
}
- if (bdi->penalty <= damp->reuse_limit / 2.0)
- bgp_damp_info_free(bdi, 1);
+ if (bdi->penalty <= bdc->reuse_limit / 2.0)
+ bgp_damp_info_free(bdi, 1, bdc->afi, bdc->safi);
else
- BGP_DAMP_LIST_ADD(damp, bdi);
+ BGP_DAMP_LIST_ADD(bdc, bdi);
} else
/* Re-insert into another list (See RFC2439 Section
* 4.8.6). */
- bgp_reuse_list_add(bdi);
+ bgp_reuse_list_add(bdi, bdc);
}
return 0;
@@ -178,6 +181,7 @@ int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_node *rn,
time_t t_now;
struct bgp_damp_info *bdi = NULL;
unsigned int last_penalty = 0;
+ struct bgp_damp_config *bdc = &damp[afi][safi];
t_now = bgp_clock();
@@ -206,18 +210,18 @@ int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_node *rn,
bdi->afi = afi;
bdi->safi = safi;
(bgp_path_info_extra_get(path))->damp_info = bdi;
- BGP_DAMP_LIST_ADD(damp, bdi);
+ BGP_DAMP_LIST_ADD(bdc, 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));
+ bdi->penalty = (bgp_damp_decay(t_now - bdi->t_updated,
+ bdi->penalty, bdc)
+ + (attr_change ? DEFAULT_PENALTY / 2
+ : DEFAULT_PENALTY));
- if (bdi->penalty > damp->ceiling)
- bdi->penalty = damp->ceiling;
+ if (bdi->penalty > bdc->ceiling)
+ bdi->penalty = bdc->ceiling;
bdi->flap++;
}
@@ -234,19 +238,19 @@ int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_node *rn,
if (CHECK_FLAG(bdi->path->flags, BGP_PATH_DAMPED)) {
/* If decay rate isn't equal to 0, reinsert brn. */
if (bdi->penalty != last_penalty && bdi->index >= 0) {
- bgp_reuse_list_delete(bdi);
- bgp_reuse_list_add(bdi);
+ bgp_reuse_list_delete(bdi, bdc);
+ bgp_reuse_list_add(bdi, bdc);
}
return BGP_DAMP_SUPPRESSED;
}
/* If not suppressed before, do annonunce this withdraw and
insert into reuse_list. */
- if (bdi->penalty >= damp->suppress_value) {
+ if (bdi->penalty >= bdc->suppress_value) {
bgp_path_info_set_flag(rn, path, BGP_PATH_DAMPED);
bdi->suppress_time = t_now;
- BGP_DAMP_LIST_DEL(damp, bdi);
- bgp_reuse_list_add(bdi);
+ BGP_DAMP_LIST_DEL(bdc, bdi);
+ bgp_reuse_list_add(bdi, bdc);
}
return BGP_DAMP_USED;
@@ -258,6 +262,7 @@ int bgp_damp_update(struct bgp_path_info *path, struct bgp_node *rn, afi_t afi,
time_t t_now;
struct bgp_damp_info *bdi;
int status;
+ struct bgp_damp_config *bdc = &damp[afi][safi];
if (!path->extra || !((bdi = path->extra->damp_info)))
return BGP_DAMP_USED;
@@ -266,76 +271,35 @@ int bgp_damp_update(struct bgp_path_info *path, struct bgp_node *rn, afi_t afi,
bgp_path_info_unset_flag(rn, path, BGP_PATH_HISTORY);
bdi->lastrecord = BGP_RECORD_UPDATE;
- bdi->penalty = bgp_damp_decay(t_now - bdi->t_updated, bdi->penalty);
+ bdi->penalty =
+ bgp_damp_decay(t_now - bdi->t_updated, bdi->penalty, bdc);
if (!CHECK_FLAG(bdi->path->flags, BGP_PATH_DAMPED)
- && (bdi->penalty < damp->suppress_value))
+ && (bdi->penalty < bdc->suppress_value))
status = BGP_DAMP_USED;
else if (CHECK_FLAG(bdi->path->flags, BGP_PATH_DAMPED)
- && (bdi->penalty < damp->reuse_limit)) {
+ && (bdi->penalty < bdc->reuse_limit)) {
bgp_path_info_unset_flag(rn, path, BGP_PATH_DAMPED);
- bgp_reuse_list_delete(bdi);
- BGP_DAMP_LIST_ADD(damp, bdi);
+ bgp_reuse_list_delete(bdi, bdc);
+ BGP_DAMP_LIST_ADD(bdc, bdi);
bdi->suppress_time = 0;
status = BGP_DAMP_USED;
} else
status = BGP_DAMP_SUPPRESSED;
- if (bdi->penalty > damp->reuse_limit / 2.0)
+ if (bdi->penalty > bdc->reuse_limit / 2.0)
bdi->t_updated = t_now;
else
- bgp_damp_info_free(bdi, 0);
+ bgp_damp_info_free(bdi, 0, afi, safi);
return status;
}
-/* Remove dampening information and history route. */
-int bgp_damp_scan(struct bgp_path_info *path, afi_t afi, safi_t safi)
-{
- time_t t_now, t_diff;
- struct bgp_damp_info *bdi;
-
- assert(path->extra && path->extra->damp_info);
-
- t_now = bgp_clock();
- bdi = path->extra->damp_info;
-
- if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
- t_diff = t_now - bdi->suppress_time;
-
- if (t_diff >= damp->max_suppress_time) {
- bgp_path_info_unset_flag(bdi->rn, path,
- BGP_PATH_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 path 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->path. */
- 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, afi_t afi,
+ safi_t safi)
{
struct bgp_path_info *path;
+ struct bgp_damp_config *bdc = &damp[afi][safi];
if (!bdi)
return;
@@ -344,9 +308,9 @@ void bgp_damp_info_free(struct bgp_damp_info *bdi, int withdraw)
path->extra->damp_info = NULL;
if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
- bgp_reuse_list_delete(bdi);
+ bgp_reuse_list_delete(bdi, bdc);
else
- BGP_DAMP_LIST_DEL(damp, bdi);
+ BGP_DAMP_LIST_DEL(bdc, bdi);
bgp_path_info_unset_flag(bdi->rn, path,
BGP_PATH_HISTORY | BGP_PATH_DAMPED);
@@ -357,68 +321,67 @@ void bgp_damp_info_free(struct bgp_damp_info *bdi, int withdraw)
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,
+ struct bgp_damp_config *bdc)
{
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;
+ bdc->suppress_value = sup;
+ bdc->half_life = hlife;
+ bdc->reuse_limit = reuse;
+ bdc->max_suppress_time = maxsup;
/* Initialize params per bgp_damp_config. */
- damp->reuse_index_size = REUSE_ARRAY_SIZE;
+ bdc->reuse_index_size = REUSE_ARRAY_SIZE;
- damp->ceiling =
- (int)(damp->reuse_limit * (pow(2,
- (double)damp->max_suppress_time
- / damp->half_life)));
+ bdc->ceiling = (int)(bdc->reuse_limit
+ * (pow(2, (double)bdc->max_suppress_time
+ / bdc->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));
+ bdc->decay_array_size = ceil((double)bdc->max_suppress_time / DELTA_T);
+ bdc->decay_array = XMALLOC(MTYPE_BGP_DAMP_ARRAY,
+ sizeof(double) * (bdc->decay_array_size));
+ bdc->decay_array[0] = 1.0;
+ bdc->decay_array[1] =
+ exp((1.0 / ((double)bdc->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];
+ for (i = 2; i < bdc->decay_array_size; i++)
+ bdc->decay_array[i] =
+ bdc->decay_array[i - 1] * bdc->decay_array[1];
/* Reuse-list computations */
- i = ceil((double)damp->max_suppress_time / DELTA_REUSE) + 1;
+ i = ceil((double)bdc->max_suppress_time / DELTA_REUSE) + 1;
if (i > REUSE_LIST_SIZE || i == 0)
i = REUSE_LIST_SIZE;
- damp->reuse_list_size = i;
+ bdc->reuse_list_size = i;
- damp->reuse_list = XCALLOC(MTYPE_BGP_DAMP_ARRAY,
- damp->reuse_list_size
- * sizeof(struct bgp_reuse_node *));
+ bdc->reuse_list =
+ XCALLOC(MTYPE_BGP_DAMP_ARRAY,
+ bdc->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);
+ bdc->reuse_index = XCALLOC(MTYPE_BGP_DAMP_ARRAY,
+ sizeof(int) * bdc->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));
+ reuse_max_ratio = (double)bdc->ceiling / bdc->reuse_limit;
+ j = (exp((double)bdc->max_suppress_time / bdc->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);
+ bdc->scale_factor =
+ (double)bdc->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))))
+ for (i = 0; i < bdc->reuse_index_size; i++) {
+ bdc->reuse_index[i] =
+ (int)(((double)bdc->half_life / DELTA_REUSE)
+ * log10(1.0
+ / (bdc->reuse_limit
+ * (1.0
+ + ((double)i / bdc->scale_factor))))
/ log10(0.5));
}
}
@@ -426,122 +389,129 @@ static void bgp_damp_parameter_set(int hlife, int reuse, int sup, int maxsup)
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)
{
+ struct bgp_damp_config *bdc = &damp[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)
+ if (bdc->half_life == half && bdc->reuse_limit == reuse
+ && bdc->suppress_value == suppress
+ && bdc->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);
+ bgp_damp_parameter_set(half, reuse, suppress, max, bdc);
/* Register reuse timer. */
- thread_add_timer(bm->master, bgp_reuse_timer, NULL, DELTA_REUSE,
- &damp->t_reuse);
+ thread_add_timer(bm->master, bgp_reuse_timer, bdc, DELTA_REUSE,
+ &bdc->t_reuse);
return 0;
}
-static void bgp_damp_config_clean(struct bgp_damp_config *damp)
+static void bgp_damp_config_clean(struct bgp_damp_config *bdc)
{
/* Free decay array */
- XFREE(MTYPE_BGP_DAMP_ARRAY, damp->decay_array);
- damp->decay_array_size = 0;
+ XFREE(MTYPE_BGP_DAMP_ARRAY, bdc->decay_array);
+ bdc->decay_array_size = 0;
/* Free reuse index array */
- XFREE(MTYPE_BGP_DAMP_ARRAY, damp->reuse_index);
- damp->reuse_index_size = 0;
+ XFREE(MTYPE_BGP_DAMP_ARRAY, bdc->reuse_index);
+ bdc->reuse_index_size = 0;
/* Free reuse list array. */
- XFREE(MTYPE_BGP_DAMP_ARRAY, damp->reuse_list);
- damp->reuse_list_size = 0;
+ XFREE(MTYPE_BGP_DAMP_ARRAY, bdc->reuse_list);
+ bdc->reuse_list_size = 0;
}
/* Clean all the bgp_damp_info stored in reuse_list. */
-void bgp_damp_info_clean(void)
+void bgp_damp_info_clean(afi_t afi, safi_t safi)
{
unsigned int i;
struct bgp_damp_info *bdi, *next;
+ struct bgp_damp_config *bdc = &damp[afi][safi];
- damp->reuse_offset = 0;
+ bdc->reuse_offset = 0;
- for (i = 0; i < damp->reuse_list_size; i++) {
- if (!damp->reuse_list[i])
+ for (i = 0; i < bdc->reuse_list_size; i++) {
+ if (!bdc->reuse_list[i])
continue;
- for (bdi = damp->reuse_list[i]; bdi; bdi = next) {
+ for (bdi = bdc->reuse_list[i]; bdi; bdi = next) {
next = bdi->next;
- bgp_damp_info_free(bdi, 1);
+ bgp_damp_info_free(bdi, 1, afi, safi);
}
- damp->reuse_list[i] = NULL;
+ bdc->reuse_list[i] = NULL;
}
- for (bdi = damp->no_reuse_list; bdi; bdi = next) {
+ for (bdi = bdc->no_reuse_list; bdi; bdi = next) {
next = bdi->next;
- bgp_damp_info_free(bdi, 1);
+ bgp_damp_info_free(bdi, 1, afi, safi);
}
- damp->no_reuse_list = NULL;
+ bdc->no_reuse_list = NULL;
}
int bgp_damp_disable(struct bgp *bgp, afi_t afi, safi_t safi)
{
+ struct bgp_damp_config *bdc = &damp[afi][safi];
/* 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;
+ if (bdc->t_reuse)
+ thread_cancel(bdc->t_reuse);
+ bdc->t_reuse = NULL;
/* Clean BGP dampening information. */
- bgp_damp_info_clean();
+ bgp_damp_info_clean(afi, safi);
/* Clear configuration */
- bgp_damp_config_clean(&bgp_damp_cfg);
+ bgp_damp_config_clean(bdc);
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, afi_t afi, safi_t safi)
{
- 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);
+ if (damp[afi][safi].half_life == DEFAULT_HALF_LIFE * 60
+ && damp[afi][safi].reuse_limit == DEFAULT_REUSE
+ && damp[afi][safi].suppress_value == DEFAULT_SUPPRESS
+ && damp[afi][safi].max_suppress_time
+ == damp[afi][safi].half_life * 4)
+ vty_out(vty, " bgp dampening\n");
+ else if (damp[afi][safi].half_life != DEFAULT_HALF_LIFE * 60
+ && damp[afi][safi].reuse_limit == DEFAULT_REUSE
+ && damp[afi][safi].suppress_value == DEFAULT_SUPPRESS
+ && damp[afi][safi].max_suppress_time
+ == damp[afi][safi].half_life * 4)
+ vty_out(vty, " bgp dampening %lld\n",
+ damp[afi][safi].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);
+ vty_out(vty, " bgp dampening %lld %d %d %lld\n",
+ damp[afi][safi].half_life / 60LL,
+ damp[afi][safi].reuse_limit,
+ damp[afi][safi].suppress_value,
+ damp[afi][safi].max_suppress_time / 60LL);
}
static const char *bgp_get_reuse_time(unsigned int penalty, char *buf,
- size_t len, bool use_json,
- json_object *json)
+ size_t len, afi_t afi, safi_t safi,
+ bool use_json, json_object *json)
{
time_t reuse_time = 0;
struct tm *tm = NULL;
int time_store = 0;
- if (penalty > damp->reuse_limit) {
+ if (penalty > damp[afi][safi].reuse_limit) {
reuse_time = (int)(DELTA_T
- * ((log((double)damp->reuse_limit / penalty))
- / (log(damp->decay_array[1]))));
+ * ((log((double)damp[afi][safi].reuse_limit
+ / penalty))
+ / (log(damp[afi][safi].decay_array[1]))));
- if (reuse_time > damp->max_suppress_time)
- reuse_time = damp->max_suppress_time;
+ if (reuse_time > damp[afi][safi].max_suppress_time)
+ reuse_time = damp[afi][safi].max_suppress_time;
tm = gmtime(&reuse_time);
} else
@@ -593,13 +563,14 @@ static const char *bgp_get_reuse_time(unsigned int penalty, char *buf,
return buf;
}
-void bgp_damp_info_vty(struct vty *vty, struct bgp_path_info *path,
- json_object *json_path)
+void bgp_damp_info_vty(struct vty *vty, struct bgp_path_info *path, afi_t afi,
+ safi_t safi, json_object *json_path)
{
struct bgp_damp_info *bdi;
time_t t_now, t_diff;
char timebuf[BGP_UPTIME_LEN];
int penalty;
+ struct bgp_damp_config *bdc = &damp[afi][safi];
if (!path->extra)
return;
@@ -609,13 +580,13 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp_path_info *path,
/* If dampening is not enabled or there is no dampening information,
return immediately. */
- if (!damp || !bdi)
+ if (!bdc || !bdi)
return;
/* Calculate new penalty. */
t_now = bgp_clock();
t_diff = t_now - bdi->t_updated;
- penalty = bgp_damp_decay(t_diff, bdi->penalty);
+ penalty = bgp_damp_decay(t_diff, bdi->penalty, bdc);
if (json_path) {
json_object_int_add(json_path, "dampeningPenalty", penalty);
@@ -625,8 +596,8 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp_path_info *path,
if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
&& !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
- bgp_get_reuse_time(penalty, timebuf, BGP_UPTIME_LEN, 1,
- json_path);
+ bgp_get_reuse_time(penalty, timebuf, BGP_UPTIME_LEN,
+ afi, safi, 1, json_path);
} else {
vty_out(vty,
" Dampinfo: penalty %d, flapped %d times in %s",
@@ -638,7 +609,7 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp_path_info *path,
&& !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
vty_out(vty, ", reuse in %s",
bgp_get_reuse_time(penalty, timebuf,
- BGP_UPTIME_LEN, 0,
+ BGP_UPTIME_LEN, afi, safi, 0,
json_path));
vty_out(vty, "\n");
@@ -646,12 +617,14 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp_path_info *path,
}
const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_path_info *path,
- char *timebuf, size_t len, bool use_json,
+ char *timebuf, size_t len, afi_t afi,
+ safi_t safi, bool use_json,
json_object *json)
{
struct bgp_damp_info *bdi;
time_t t_now, t_diff;
int penalty;
+ struct bgp_damp_config *bdc = &damp[afi][safi];
if (!path->extra)
return NULL;
@@ -661,15 +634,16 @@ const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_path_info *path,
/* If dampening is not enabled or there is no dampening information,
return immediately. */
- if (!damp || !bdi)
+ if (!bdc || !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);
+ penalty = bgp_damp_decay(t_diff, bdi->penalty, bdc);
- return bgp_get_reuse_time(penalty, timebuf, len, use_json, json);
+ return bgp_get_reuse_time(penalty, timebuf, len, afi, safi, use_json,
+ json);
}
int bgp_show_dampening_parameters(struct vty *vty, afi_t afi, safi_t safi)
@@ -684,12 +658,15 @@ int bgp_show_dampening_parameters(struct vty *vty, afi_t afi, safi_t safi)
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);
+ (long long)damp[afi][safi].half_life / 60);
+ vty_out(vty, "Reuse penalty: %d\n",
+ damp[afi][safi].reuse_limit);
+ vty_out(vty, "Suppress penalty: %d\n",
+ damp[afi][safi].suppress_value);
vty_out(vty, "Max suppress time: %lld min\n",
- (long long)damp->max_suppress_time / 60);
- vty_out(vty, "Max suppress penalty: %u\n", damp->ceiling);
+ (long long)damp[afi][safi].max_suppress_time / 60);
+ vty_out(vty, "Max suppress penalty: %u\n",
+ damp[afi][safi].ceiling);
vty_out(vty, "\n");
} else
vty_out(vty, "dampening not enabled for %s\n",