Revert "bgpd: peer / peer group dampening profiles"

This reverts commit 40ec3340be.

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
This commit is contained in:
Igor Ryzhov 2021-08-02 13:26:58 +03:00
parent 6c75f4b3c7
commit b4f7f45b94
7 changed files with 185 additions and 502 deletions

View File

@ -37,115 +37,19 @@
#include "bgpd/bgp_advertise.h"
#include "bgpd/bgp_vty.h"
static void bgp_reuselist_add(struct reuselist *list,
struct bgp_damp_info *info)
{
struct reuselist_node *new_node;
/* Global variable to access damping configuration */
static struct bgp_damp_config damp[AFI_MAX][SAFI_MAX];
assert(info);
new_node = XCALLOC(MTYPE_BGP_DAMP_REUSELIST, sizeof(*new_node));
new_node->info = info;
SLIST_INSERT_HEAD(list, new_node, entry);
}
static void bgp_reuselist_del(struct reuselist *list,
struct reuselist_node **node)
{
if ((*node) == NULL)
return;
assert(list && node && *node);
SLIST_REMOVE(list, (*node), reuselist_node, entry);
XFREE(MTYPE_BGP_DAMP_REUSELIST, (*node));
*node = NULL;
}
static void bgp_reuselist_switch(struct reuselist *source,
struct reuselist_node *node,
struct reuselist *target)
{
assert(source && target && node);
SLIST_REMOVE(source, node, reuselist_node, entry);
SLIST_INSERT_HEAD(target, node, entry);
}
static void bgp_reuselist_free(struct reuselist *list)
{
struct reuselist_node *rn;
assert(list);
while ((rn = SLIST_FIRST(list)) != NULL)
bgp_reuselist_del(list, &rn);
}
static struct reuselist_node *bgp_reuselist_find(struct reuselist *list,
struct bgp_damp_info *info)
{
struct reuselist_node *rn;
assert(list && info);
SLIST_FOREACH (rn, list, entry) {
if (rn->info == info)
return rn;
}
return NULL;
}
static void bgp_damp_info_unclaim(struct bgp_damp_info *bdi)
{
struct reuselist_node *node;
assert(bdi && bdi->config);
if (bdi->index == BGP_DAMP_NO_REUSE_LIST_INDEX) {
node = bgp_reuselist_find(&bdi->config->no_reuse_list, bdi);
if (node)
bgp_reuselist_del(&bdi->config->no_reuse_list, &node);
} else {
node = bgp_reuselist_find(&bdi->config->reuse_list[bdi->index],
bdi);
if (node)
bgp_reuselist_del(&bdi->config->reuse_list[bdi->index],
&node);
}
bdi->config = NULL;
}
static void bgp_damp_info_claim(struct bgp_damp_info *bdi,
struct bgp_damp_config *bdc)
{
assert(bdc && bdi);
if (bdi->config == NULL) {
bdi->config = bdc;
return;
}
bgp_damp_info_unclaim(bdi);
bdi->config = bdc;
bdi->afi = bdc->afi;
bdi->safi = bdc->safi;
}
struct bgp_damp_config *get_active_bdc_from_pi(struct bgp_path_info *pi,
afi_t afi, safi_t safi)
{
if (!pi)
return NULL;
if (CHECK_FLAG(pi->peer->af_flags[afi][safi],
PEER_FLAG_CONFIG_DAMPENING))
return &pi->peer->damp[afi][safi];
if (peer_group_active(pi->peer))
if (CHECK_FLAG(pi->peer->group->conf->af_flags[afi][safi],
PEER_FLAG_CONFIG_DAMPENING))
return &pi->peer->group->conf->damp[afi][safi];
if (CHECK_FLAG(pi->peer->bgp->af_flags[afi][safi],
BGP_CONFIG_DAMPENING))
return &pi->peer->bgp->damp[afi][safi];
return NULL;
}
/* Utility macro to add and delete BGP dampening information to no
used list. */
#define BGP_DAMP_LIST_ADD(N, A) BGP_PATH_INFO_ADD(N, A, no_reuse_list)
#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, struct bgp_damp_config *bdc)
{
unsigned int i;
unsigned int index;
int index;
/*
* reuse_limit can't be zero, this is for Coverity
@ -168,45 +72,27 @@ static int bgp_reuse_index(int penalty, struct bgp_damp_config *bdc)
static void bgp_reuse_list_add(struct bgp_damp_info *bdi,
struct bgp_damp_config *bdc)
{
bgp_damp_info_claim(bdi, bdc);
bdi->index = bgp_reuse_index(bdi->penalty, bdc);
bgp_reuselist_add(&bdc->reuse_list[bdi->index], bdi);
int index;
index = bdi->index = bgp_reuse_index(bdi->penalty, bdc);
bdi->prev = NULL;
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,
struct bgp_damp_config *bdc)
{
struct reuselist *list;
struct reuselist_node *rn;
list = &bdc->reuse_list[bdi->index];
rn = bgp_reuselist_find(list, bdi);
bgp_damp_info_unclaim(bdi);
bgp_reuselist_del(list, &rn);
}
static void bgp_no_reuse_list_add(struct bgp_damp_info *bdi,
struct bgp_damp_config *bdc)
{
bgp_damp_info_claim(bdi, bdc);
bdi->index = BGP_DAMP_NO_REUSE_LIST_INDEX;
bgp_reuselist_add(&bdc->no_reuse_list, bdi);
}
static void bgp_no_reuse_list_delete(struct bgp_damp_info *bdi,
struct bgp_damp_config *bdc)
{
struct reuselist_node *rn;
assert(bdc && bdi);
if (bdi->config == NULL) {
bgp_damp_info_unclaim(bdi);
return;
}
bdi->config = NULL;
rn = bgp_reuselist_find(&bdc->no_reuse_list, bdi);
bgp_reuselist_del(&bdc->no_reuse_list, &rn);
if (bdi->next)
bdi->next->prev = bdi->prev;
if (bdi->prev)
bdi->prev->next = bdi->next;
else
bdc->reuse_list[bdi->index] = bdi->next;
}
/* Return decayed penalty value. */
@ -229,34 +115,32 @@ int bgp_damp_decay(time_t tdiff, int penalty, struct bgp_damp_config *bdc)
is evaluated. RFC2439 Section 4.8.7. */
static int bgp_reuse_timer(struct thread *t)
{
struct bgp_damp_config *bdc = THREAD_ARG(t);
struct bgp_damp_info *bdi;
struct reuselist plist;
struct reuselist_node *node;
struct bgp *bgp;
struct bgp_damp_info *next;
time_t t_now, t_diff;
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 queue head and zero the list head
* list head entry. */
assert(bdc->reuse_offset < bdc->reuse_list_size);
plist = bdc->reuse_list[bdc->reuse_offset];
node = SLIST_FIRST(&plist);
SLIST_INIT(&bdc->reuse_list[bdc->reuse_offset]);
/* 1. save a pointer to the current zeroth queue head and zero the
list head entry. */
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. */
bdc->reuse_offset = (bdc->reuse_offset + 1) % bdc->reuse_list_size;
assert(bdc->reuse_offset < bdc->reuse_list_size);
/* 3. if ( the saved list head pointer is non-empty ) */
while ((node = SLIST_FIRST(&plist)) != NULL) {
bdi = node->info;
bgp = bdi->path->peer->bgp;
for (; bdi; bdi = next) {
struct bgp *bgp = bdi->path->peer->bgp;
next = bdi->next;
/* Set t-diff = t-now - t-updated. */
t_diff = t_now - bdi->t_updated;
@ -285,27 +169,16 @@ static int bgp_reuse_timer(struct thread *t)
bdi->safi);
}
if (bdi->penalty <= bdc->reuse_limit / 2.0) {
bgp_damp_info_free(&bdi, bdc, 1, bdi->afi,
bdi->safi);
bgp_reuselist_del(&plist, &node);
} else {
node->info->index =
BGP_DAMP_NO_REUSE_LIST_INDEX;
bgp_reuselist_switch(&plist, node,
&bdc->no_reuse_list);
}
} else {
if (bdi->penalty <= bdc->reuse_limit / 2.0)
bgp_damp_info_free(bdi, 1, bdc->afi, bdc->safi);
else
BGP_DAMP_LIST_ADD(bdc, bdi);
} else
/* Re-insert into another list (See RFC2439 Section
* 4.8.6). */
bdi->index = bgp_reuse_index(bdi->penalty, bdc);
bgp_reuselist_switch(&plist, node,
&bdc->reuse_list[bdi->index]);
}
bgp_reuse_list_add(bdi, bdc);
}
assert(SLIST_EMPTY(&plist));
return 0;
}
@ -316,13 +189,10 @@ int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest,
time_t t_now;
struct bgp_damp_info *bdi = NULL;
unsigned int last_penalty = 0;
struct bgp_damp_config *bdc;
bdc = get_active_bdc_from_pi(path, afi, safi);
if (!bdc)
return BGP_DAMP_USED;
struct bgp_damp_config *bdc = &damp[afi][safi];
t_now = bgp_clock();
/* Processing Unreachable Messages. */
if (path->extra)
bdi = path->extra->damp_info;
@ -344,13 +214,12 @@ int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest,
bdi->flap = 1;
bdi->start_time = t_now;
bdi->suppress_time = 0;
bdi->index = BGP_DAMP_NO_REUSE_LIST_INDEX;
bdi->index = -1;
bdi->afi = afi;
bdi->safi = safi;
(bgp_path_info_extra_get(path))->damp_info = bdi;
bgp_no_reuse_list_add(bdi, bdc);
BGP_DAMP_LIST_ADD(bdc, bdi);
} else {
bgp_damp_info_claim(bdi, bdc);
last_penalty = bdi->penalty;
/* 1. Set t-diff = t-now - t-updated. */
@ -376,7 +245,7 @@ int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest,
/* Remove the route from a reuse list if it is on one. */
if (CHECK_FLAG(bdi->path->flags, BGP_PATH_DAMPED)) {
/* If decay rate isn't equal to 0, reinsert brn. */
if (bdi->penalty != last_penalty) {
if (bdi->penalty != last_penalty && bdi->index >= 0) {
bgp_reuse_list_delete(bdi, bdc);
bgp_reuse_list_add(bdi, bdc);
}
@ -388,9 +257,10 @@ int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest,
if (bdi->penalty >= bdc->suppress_value) {
bgp_path_info_set_flag(dest, path, BGP_PATH_DAMPED);
bdi->suppress_time = t_now;
bgp_no_reuse_list_delete(bdi, bdc);
BGP_DAMP_LIST_DEL(bdc, bdi);
bgp_reuse_list_add(bdi, bdc);
}
return BGP_DAMP_USED;
}
@ -400,10 +270,7 @@ int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest,
time_t t_now;
struct bgp_damp_info *bdi;
int status;
struct bgp_damp_config *bdc;
bdc = get_active_bdc_from_pi(path, afi, safi);
assert(bdc);
struct bgp_damp_config *bdc = &damp[afi][safi];
if (!path->extra || !((bdi = path->extra->damp_info)))
return BGP_DAMP_USED;
@ -422,7 +289,7 @@ int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest,
&& (bdi->penalty < bdc->reuse_limit)) {
bgp_path_info_unset_flag(dest, path, BGP_PATH_DAMPED);
bgp_reuse_list_delete(bdi, bdc);
bgp_no_reuse_list_add(bdi, bdc);
BGP_DAMP_LIST_ADD(bdc, bdi);
bdi->suppress_time = 0;
status = BGP_DAMP_USED;
} else
@ -430,29 +297,36 @@ int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest,
if (bdi->penalty > bdc->reuse_limit / 2.0)
bdi->t_updated = t_now;
else {
bgp_damp_info_unclaim(bdi);
bgp_damp_info_free(&bdi, bdc, 0, afi, safi);
}
else
bgp_damp_info_free(bdi, 0, afi, safi);
return status;
}
void bgp_damp_info_free(struct bgp_damp_info **bdi, struct bgp_damp_config *bdc,
int withdraw, afi_t afi, safi_t safi)
void bgp_damp_info_free(struct bgp_damp_info *bdi, int withdraw, afi_t afi,
safi_t safi)
{
assert(bdc && bdi && *bdi);
struct bgp_path_info *path;
struct bgp_damp_config *bdc = &damp[afi][safi];
if ((*bdi)->path == NULL) {
XFREE(MTYPE_BGP_DAMP_INFO, (*bdi));
if (!bdi)
return;
}
(*bdi)->path->extra->damp_info = NULL;
bgp_path_info_unset_flag((*bdi)->dest, (*bdi)->path,
path = bdi->path;
path->extra->damp_info = NULL;
if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
bgp_reuse_list_delete(bdi, bdc);
else
BGP_DAMP_LIST_DEL(bdc, bdi);
bgp_path_info_unset_flag(bdi->dest, path,
BGP_PATH_HISTORY | BGP_PATH_DAMPED);
if ((*bdi)->lastrecord == BGP_RECORD_WITHDRAW && withdraw)
bgp_path_info_delete((*bdi)->dest, (*bdi)->path);
if (bdi->lastrecord == BGP_RECORD_WITHDRAW && withdraw)
bgp_path_info_delete(bdi->dest, path);
XFREE(MTYPE_BGP_DAMP_INFO, bdi);
}
static void bgp_damp_parameter_set(int hlife, int reuse, int sup, int maxsup,
@ -495,7 +369,8 @@ static void bgp_damp_parameter_set(int hlife, int reuse, int sup, int maxsup,
bdc->reuse_list =
XCALLOC(MTYPE_BGP_DAMP_ARRAY,
bdc->reuse_list_size * sizeof(struct reuselist));
bdc->reuse_list_size * sizeof(struct bgp_reuse_node *));
/* Reuse-array computations */
bdc->reuse_index = XCALLOC(MTYPE_BGP_DAMP_ARRAY,
sizeof(int) * bdc->reuse_index_size);
@ -522,7 +397,7 @@ 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 = &bgp->damp[afi][safi];
struct bgp_damp_config *bdc = &damp[afi][safi];
if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) {
if (bdc->half_life == half && bdc->reuse_limit == reuse
@ -534,8 +409,6 @@ int bgp_damp_enable(struct bgp *bgp, afi_t afi, safi_t safi, time_t half,
SET_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING);
bgp_damp_parameter_set(half, reuse, suppress, max, bdc);
bdc->afi = afi;
bdc->safi = safi;
/* Register reuse timer. */
thread_add_timer(bm->master, bgp_reuse_timer, bdc, DELTA_REUSE,
@ -544,30 +417,8 @@ int bgp_damp_enable(struct bgp *bgp, afi_t afi, safi_t safi, time_t half,
return 0;
}
/* Clean all the bgp_damp_info stored in reuse_list and no_reuse_list. */
void bgp_damp_info_clean(struct bgp_damp_config *bdc, afi_t afi, safi_t safi)
static void bgp_damp_config_clean(struct bgp_damp_config *bdc)
{
struct bgp_damp_info *bdi;
struct reuselist_node *rn;
struct reuselist *list;
unsigned int i;
bdc->reuse_offset = 0;
for (i = 0; i < bdc->reuse_list_size; ++i) {
list = &bdc->reuse_list[i];
while ((rn = SLIST_FIRST(list)) != NULL) {
bdi = rn->info;
bgp_reuselist_del(list, &rn);
bgp_damp_info_free(&bdi, bdc, 1, afi, safi);
}
}
while ((rn = SLIST_FIRST(&bdc->no_reuse_list)) != NULL) {
bdi = rn->info;
bgp_reuselist_del(&bdc->no_reuse_list, &rn);
bgp_damp_info_free(&bdi, bdc, 1, afi, safi);
}
/* Free decay array */
XFREE(MTYPE_BGP_DAMP_ARRAY, bdc->decay_array);
bdc->decay_array_size = 0;
@ -577,81 +428,96 @@ void bgp_damp_info_clean(struct bgp_damp_config *bdc, afi_t afi, safi_t safi)
bdc->reuse_index_size = 0;
/* Free reuse list array. */
for (i = 0; i < bdc->reuse_list_size; ++i)
bgp_reuselist_free(&bdc->reuse_list[i]);
XFREE(MTYPE_BGP_DAMP_ARRAY, bdc->reuse_list);
bdc->reuse_list_size = 0;
THREAD_OFF(bdc->t_reuse);
}
/* Disable route flap dampening for a bgp instance.
*
* Please note that this function also gets used to free memory when deleting a
* bgp instance.
*/
/* Clean all the bgp_damp_info stored in reuse_list. */
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];
bdc->reuse_offset = 0;
for (i = 0; i < bdc->reuse_list_size; i++) {
if (!bdc->reuse_list[i])
continue;
for (bdi = bdc->reuse_list[i]; bdi; bdi = next) {
next = bdi->next;
bgp_damp_info_free(bdi, 1, afi, safi);
}
bdc->reuse_list[i] = NULL;
}
for (bdi = bdc->no_reuse_list; bdi; bdi = next) {
next = bdi->next;
bgp_damp_info_free(bdi, 1, afi, safi);
}
bdc->no_reuse_list = NULL;
}
int bgp_damp_disable(struct bgp *bgp, afi_t afi, safi_t safi)
{
struct bgp_damp_config *bdc;
bdc = &bgp->damp[afi][safi];
if (!bdc)
return 0;
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 event. */
thread_cancel(&bdc->t_reuse);
thread_cancel(&(bdc->t_reuse));
/* Clean BGP dampening information. */
bgp_damp_info_clean(bdc, afi, safi);
bgp_damp_info_clean(afi, safi);
/* Clear configuration */
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, struct bgp *bgp, afi_t afi,
safi_t safi)
void bgp_config_write_damp(struct vty *vty, afi_t afi, safi_t safi)
{
struct bgp_damp_config *bdc;
bdc = &bgp->damp[afi][safi];
if (bdc->half_life == DEFAULT_HALF_LIFE * 60
&& bdc->reuse_limit == DEFAULT_REUSE
&& bdc->suppress_value == DEFAULT_SUPPRESS
&& bdc->max_suppress_time == bdc->half_life * 4)
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 (bdc->half_life != DEFAULT_HALF_LIFE * 60
&& bdc->reuse_limit == DEFAULT_REUSE
&& bdc->suppress_value == DEFAULT_SUPPRESS
&& bdc->max_suppress_time == bdc->half_life * 4)
vty_out(vty, " bgp dampening %lld\n", bdc->half_life / 60LL);
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",
bdc->half_life / 60LL, bdc->reuse_limit,
bdc->suppress_value, bdc->max_suppress_time / 60LL);
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(struct bgp_damp_config *bdc,
unsigned int penalty, char *buf,
size_t len, bool use_json,
json_object *json)
static const char *bgp_get_reuse_time(unsigned int penalty, char *buf,
size_t len, afi_t afi, safi_t safi,
bool use_json, json_object *json)
{
time_t reuse_time = 0;
struct tm tm;
int time_store = 0;
if (penalty > bdc->reuse_limit) {
if (penalty > damp[afi][safi].reuse_limit) {
reuse_time = (int)(DELTA_T
* ((log((double)bdc->reuse_limit / penalty))
/ (log(bdc->decay_array[1]))));
* ((log((double)damp[afi][safi].reuse_limit
/ penalty))
/ (log(damp[afi][safi].decay_array[1]))));
if (reuse_time > bdc->max_suppress_time)
reuse_time = bdc->max_suppress_time;
if (reuse_time > damp[afi][safi].max_suppress_time)
reuse_time = damp[afi][safi].max_suppress_time;
gmtime_r(&reuse_time, &tm);
} else
@ -703,15 +569,14 @@ static const char *bgp_get_reuse_time(struct bgp_damp_config *bdc,
return buf;
}
void bgp_damp_info_vty(struct vty *vty, struct bgp *bgp,
struct bgp_path_info *path, afi_t afi, safi_t safi,
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 = &bgp->damp[afi][safi];
struct bgp_damp_config *bdc = &damp[afi][safi];
if (!path->extra)
return;
@ -737,8 +602,8 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp *bgp,
if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
&& !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
bgp_get_reuse_time(bdc, 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",
@ -749,15 +614,14 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp *bgp,
if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
&& !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
vty_out(vty, ", reuse in %s",
bgp_get_reuse_time(bdc, penalty, timebuf,
BGP_UPTIME_LEN, 0,
bgp_get_reuse_time(penalty, timebuf,
BGP_UPTIME_LEN, afi, safi, 0,
json_path));
vty_out(vty, "\n");
}
}
const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_path_info *path,
char *timebuf, size_t len, afi_t afi,
safi_t safi, bool use_json,
@ -766,11 +630,7 @@ const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_path_info *path,
struct bgp_damp_info *bdi;
time_t t_now, t_diff;
int penalty;
struct bgp_damp_config *bdc;
bdc = get_active_bdc_from_pi(path, afi, safi);
if (!bdc)
return NULL;
struct bgp_damp_config *bdc = &damp[afi][safi];
if (!path->extra)
return NULL;
@ -788,23 +648,24 @@ const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_path_info *path,
t_diff = t_now - bdi->t_updated;
penalty = bgp_damp_decay(t_diff, bdi->penalty, bdc);
return bgp_get_reuse_time(bdc, penalty, timebuf, len, use_json, json);
return bgp_get_reuse_time(penalty, timebuf, len, afi, safi, use_json,
json);
}
static int bgp_print_dampening_parameters(struct bgp *bgp, struct vty *vty,
afi_t afi, safi_t safi)
{
struct bgp_damp_config *bdc;
if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) {
bdc = &bgp->damp[afi][safi];
vty_out(vty, "Half-life time: %lld min\n",
(long long)bdc->half_life / 60);
vty_out(vty, "Reuse penalty: %d\n", bdc->reuse_limit);
vty_out(vty, "Suppress penalty: %d\n", bdc->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)bdc->max_suppress_time / 60);
vty_out(vty, "Max suppress penalty: %u\n", bdc->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",
@ -817,8 +678,8 @@ int bgp_show_dampening_parameters(struct vty *vty, afi_t afi, safi_t safi,
uint16_t show_flags)
{
struct bgp *bgp;
bgp = bgp_get_default();
if (bgp == NULL) {
vty_out(vty, "No BGP process is configured\n");
return CMD_WARNING;
@ -857,132 +718,3 @@ int bgp_show_dampening_parameters(struct vty *vty, afi_t afi, safi_t safi,
}
return CMD_SUCCESS;
}
void bgp_peer_damp_enable(struct peer *peer, afi_t afi, safi_t safi,
time_t half, unsigned int reuse,
unsigned int suppress, time_t max)
{
struct bgp_damp_config *bdc;
if (!peer)
return;
bdc = &peer->damp[afi][safi];
if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_CONFIG_DAMPENING)) {
if (bdc->half_life == half && bdc->reuse_limit == reuse
&& bdc->suppress_value == suppress
&& bdc->max_suppress_time == max)
return;
bgp_peer_damp_disable(peer, afi, safi);
}
SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_CONFIG_DAMPENING);
bgp_damp_parameter_set(half, reuse, suppress, max, bdc);
bdc->afi = afi;
bdc->safi = safi;
thread_add_timer(bm->master, bgp_reuse_timer, bdc, DELTA_REUSE,
&bdc->t_reuse);
}
/* Disable route flap dampening for a peer.
*
* Please note that this function also gets used to free memory when deleting a
* peer or peer group.
*/
void bgp_peer_damp_disable(struct peer *peer, afi_t afi, safi_t safi)
{
struct bgp_damp_config *bdc;
if (!peer_af_flag_check(peer, afi, safi, PEER_FLAG_CONFIG_DAMPENING))
return;
bdc = &peer->damp[afi][safi];
if (!bdc)
return;
bgp_damp_info_clean(bdc, afi, safi);
UNSET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_CONFIG_DAMPENING);
}
void bgp_config_write_peer_damp(struct vty *vty, struct peer *peer, afi_t afi,
safi_t safi)
{
struct bgp_damp_config *bdc;
bdc = &peer->damp[afi][safi];
if (bdc->half_life == DEFAULT_HALF_LIFE * 60
&& bdc->reuse_limit == DEFAULT_REUSE
&& bdc->suppress_value == DEFAULT_SUPPRESS
&& bdc->max_suppress_time == bdc->half_life * 4)
vty_out(vty, " neighbor %s dampening\n", peer->host);
else if (bdc->half_life != DEFAULT_HALF_LIFE * 60
&& bdc->reuse_limit == DEFAULT_REUSE
&& bdc->suppress_value == DEFAULT_SUPPRESS
&& bdc->max_suppress_time == bdc->half_life * 4)
vty_out(vty, " neighbor %s dampening %lld\n", peer->host,
bdc->half_life / 60LL);
else
vty_out(vty, " neighbor %s dampening %lld %d %d %lld\n",
peer->host, bdc->half_life / 60LL, bdc->reuse_limit,
bdc->suppress_value, bdc->max_suppress_time / 60LL);
}
static void bgp_print_peer_dampening_parameters(struct vty *vty,
struct peer *peer, afi_t afi,
safi_t safi, bool use_json,
json_object *json)
{
struct bgp_damp_config *bdc;
if (!peer)
return;
if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_CONFIG_DAMPENING)) {
bdc = &peer->damp[afi][safi];
if (!bdc)
return;
if (use_json) {
json_object_int_add(json, "halfLifeSecs",
bdc->half_life);
json_object_int_add(json, "reusePenalty",
bdc->reuse_limit);
json_object_int_add(json, "suppressPenalty",
bdc->suppress_value);
json_object_int_add(json, "maxSuppressTimeSecs",
bdc->max_suppress_time);
json_object_int_add(json, "maxSuppressPenalty",
bdc->ceiling);
} else {
vty_out(vty, "Half-life time: %lld min\n",
(long long)bdc->half_life / 60);
vty_out(vty, "Reuse penalty: %d\n", bdc->reuse_limit);
vty_out(vty, "Suppress penalty: %d\n",
bdc->suppress_value);
vty_out(vty, "Max suppress time: %lld min\n",
(long long)bdc->max_suppress_time / 60);
vty_out(vty, "Max suppress penalty: %u\n",
bdc->ceiling);
vty_out(vty, "\n");
}
} else if (!use_json)
vty_out(vty, "neighbor dampening not enabled for %s\n",
get_afi_safi_str(afi, safi, false));
}
void bgp_show_peer_dampening_parameters(struct vty *vty, struct peer *peer,
afi_t afi, safi_t safi, bool use_json)
{
json_object *json;
if (use_json) {
json = json_object_new_object();
json_object_string_add(json, "addressFamily",
get_afi_safi_str(afi, safi, false));
bgp_print_peer_dampening_parameters(vty, peer, afi, safi, true,
json);
vty_out(vty, "%s\n",
json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json);
} else {
vty_out(vty, "\nFor address family: %s\n",
get_afi_safi_str(afi, safi, false));
bgp_print_peer_dampening_parameters(vty, peer, afi, safi, false,
NULL);
}
}

View File

@ -25,6 +25,11 @@
/* Structure maintained on a per-route basis. */
struct bgp_damp_info {
/* Doubly linked list. This information must be linked to
reuse_list or no_reuse_list. */
struct bgp_damp_info *next;
struct bgp_damp_info *prev;
/* Figure-of-merit. */
unsigned int penalty;
@ -40,9 +45,6 @@ struct bgp_damp_info {
/* Time of route start to be suppressed. */
time_t suppress_time;
/* Back reference to associated dampening configuration. */
struct bgp_damp_config *config;
/* Back reference to bgp_path_info. */
struct bgp_path_info *path;
@ -51,8 +53,6 @@ struct bgp_damp_info {
/* Current index in the reuse_list. */
int index;
#define BGP_DAMP_NO_REUSE_LIST_INDEX \
(-1) /* index for elements on no_reuse_list */
/* Last time message type. */
uint8_t lastrecord;
@ -63,13 +63,6 @@ struct bgp_damp_info {
safi_t safi;
};
struct reuselist_node {
SLIST_ENTRY(reuselist_node) entry;
struct bgp_damp_info *info;
};
SLIST_HEAD(reuselist, reuselist_node);
/* Specified parameter set configuration. */
struct bgp_damp_config {
/* Value over which routes suppressed. */
@ -107,11 +100,11 @@ struct bgp_damp_config {
int *reuse_index;
/* Reuse list array per-set based. */
struct reuselist *reuse_list;
unsigned int reuse_offset;
struct bgp_damp_info **reuse_list;
int reuse_offset;
/* All dampening information which is not on reuse list. */
struct reuselist no_reuse_list;
struct bgp_damp_info *no_reuse_list;
/* Reuse timer thread per-set base. */
struct thread *t_reuse;
@ -139,8 +132,6 @@ struct bgp_damp_config {
#define REUSE_LIST_SIZE 256
#define REUSE_ARRAY_SIZE 1024
extern struct bgp_damp_config *get_active_bdc_from_pi(struct bgp_path_info *pi,
afi_t afi, safi_t safi);
extern int bgp_damp_enable(struct bgp *, afi_t, safi_t, time_t, unsigned int,
unsigned int, time_t);
extern int bgp_damp_disable(struct bgp *, afi_t, safi_t);
@ -148,18 +139,13 @@ extern int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest,
afi_t afi, safi_t safi, int attr_change);
extern int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest,
afi_t afi, safi_t saff);
extern void bgp_damp_info_free(struct bgp_damp_info **path,
struct bgp_damp_config *bdc, int withdraw,
extern void bgp_damp_info_free(struct bgp_damp_info *path, int withdraw,
afi_t afi, safi_t safi);
extern void bgp_damp_info_clean(struct bgp_damp_config *bdc, afi_t afi,
safi_t safi);
extern void bgp_damp_config_clean(struct bgp_damp_config *bdc);
extern void bgp_damp_info_clean(afi_t afi, safi_t safi);
extern int bgp_damp_decay(time_t, int, struct bgp_damp_config *damp);
extern void bgp_config_write_damp(struct vty *vty, struct bgp *bgp, afi_t afi,
safi_t safi);
extern void bgp_damp_info_vty(struct vty *vty, struct bgp *bgp,
struct bgp_path_info *path, afi_t afi,
safi_t safi, json_object *json_path);
extern void bgp_config_write_damp(struct vty *, afi_t afi, safi_t safi);
extern void bgp_damp_info_vty(struct vty *vty, struct bgp_path_info *path,
afi_t afi, safi_t safi, json_object *json_path);
extern const char *bgp_damp_reuse_time_vty(struct vty *vty,
struct bgp_path_info *path,
char *timebuf, size_t len, afi_t afi,
@ -167,14 +153,5 @@ extern const char *bgp_damp_reuse_time_vty(struct vty *vty,
json_object *json);
extern int bgp_show_dampening_parameters(struct vty *vty, afi_t, safi_t,
uint16_t);
extern void bgp_peer_damp_enable(struct peer *peer, afi_t afi, safi_t safi,
time_t half, unsigned int reuse,
unsigned int suppress, time_t max);
extern void bgp_peer_damp_disable(struct peer *peer, afi_t afi, safi_t safi);
extern void bgp_config_write_peer_damp(struct vty *vty, struct peer *peer,
afi_t afi, safi_t safi);
extern void bgp_show_peer_dampening_parameters(struct vty *vty,
struct peer *peer, afi_t afi,
safi_t safi, bool use_json);
#endif /* _QUAGGA_BGP_DAMP_H */

View File

@ -100,7 +100,6 @@ DEFINE_MTYPE(BGPD, PEER_UPDATE_SOURCE, "BGP peer update interface");
DEFINE_MTYPE(BGPD, PEER_CONF_IF, "BGP peer config interface");
DEFINE_MTYPE(BGPD, BGP_DAMP_INFO, "Dampening info");
DEFINE_MTYPE(BGPD, BGP_DAMP_ARRAY, "BGP Dampening array");
DEFINE_MTYPE(BGPD, BGP_DAMP_REUSELIST, "BGP Dampening reuse list");
DEFINE_MTYPE(BGPD, BGP_REGEXP, "BGP regexp");
DEFINE_MTYPE(BGPD, BGP_AGGREGATE, "BGP aggregate");
DEFINE_MTYPE(BGPD, BGP_ADDR, "BGP own address");

View File

@ -96,7 +96,6 @@ DECLARE_MTYPE(PEER_UPDATE_SOURCE);
DECLARE_MTYPE(PEER_CONF_IF);
DECLARE_MTYPE(BGP_DAMP_INFO);
DECLARE_MTYPE(BGP_DAMP_ARRAY);
DECLARE_MTYPE(BGP_DAMP_REUSELIST);
DECLARE_MTYPE(BGP_REGEXP);
DECLARE_MTYPE(BGP_AGGREGATE);
DECLARE_MTYPE(BGP_ADDR);

View File

@ -221,6 +221,9 @@ void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
return;
e = *extra;
if (e->damp_info)
bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
e->damp_info->safi);
e->damp_info = NULL;
if (e->parent) {
@ -3391,16 +3394,14 @@ static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
/* apply dampening, if result is suppressed, we'll be retaining
* the bgp_path_info in the RIB for historical reference.
*/
if (peer->sort == BGP_PEER_EBGP) {
if (get_active_bdc_from_pi(pi, afi, safi)) {
if (bgp_damp_withdraw(pi, dest, afi, safi, 0)
== BGP_DAMP_SUPPRESSED) {
bgp_aggregate_decrement(peer->bgp, p, pi, afi,
safi);
return;
}
if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
&& peer->sort == BGP_PEER_EBGP)
if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
== BGP_DAMP_SUPPRESSED) {
bgp_aggregate_decrement(peer->bgp, p, pi, afi,
safi);
return;
}
}
#ifdef ENABLE_BGP_VNC
if (safi == SAFI_MPLS_VPN) {
@ -3848,7 +3849,8 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
|| memcmp(&(bgp_path_info_extra_get(pi))->label, label,
num_labels * sizeof(mpls_label_t))
== 0)) {
if (get_active_bdc_from_pi(pi, afi, safi)
if (CHECK_FLAG(bgp->af_flags[afi][safi],
BGP_CONFIG_DAMPENING)
&& peer->sort == BGP_PEER_EBGP
&& CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
if (bgp_debug_update(peer, p, NULL, 1)) {
@ -3942,11 +3944,11 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
bgp_aggregate_decrement(bgp, p, pi, afi, safi);
/* Update bgp route dampening information. */
if (get_active_bdc_from_pi(pi, afi, safi)
if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
&& peer->sort == BGP_PEER_EBGP) {
/* This is implicit withdraw so we should update
* dampening information.
*/
dampening
information. */
if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
bgp_damp_withdraw(pi, dest, afi, safi, 1);
}
@ -4069,7 +4071,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
#endif
/* Update bgp route dampening information. */
if (get_active_bdc_from_pi(pi, afi, safi)
if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
&& peer->sort == BGP_PEER_EBGP) {
/* Now we do normal update dampening. */
ret = bgp_damp_update(pi, dest, afi, safi);
@ -10573,7 +10575,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
}
if (path->extra && path->extra->damp_info)
bgp_damp_info_vty(vty, bgp, path, afi, safi, json_path);
bgp_damp_info_vty(vty, path, afi, safi, json_path);
/* Remote Label */
if (path->extra && bgp_is_valid_label(&path->extra->label[0])
@ -14758,8 +14760,7 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
if (pi->extra && pi->extra->damp_info) {
pi_temp = pi->next;
bgp_damp_info_free(
&pi->extra->damp_info,
&bgp->damp[afi][safi],
pi->extra->damp_info,
1, afi, safi);
pi = pi_temp;
} else
@ -14781,8 +14782,7 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
if (pi->extra && pi->extra->damp_info) {
pi_temp = pi->next;
bgp_damp_info_free(
&pi->extra->damp_info,
&bgp->damp[afi][safi],
pi->extra->damp_info,
1, afi, safi);
pi = pi_temp;
} else
@ -14805,9 +14805,7 @@ DEFUN (clear_ip_bgp_dampening,
BGP_STR
"Clear route flap dampening information\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_damp_info_clean(&bgp->damp[AFI_IP][SAFI_UNICAST], AFI_IP,
SAFI_UNICAST);
bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
return CMD_SUCCESS;
}

View File

@ -2408,14 +2408,6 @@ int peer_delete(struct peer *peer)
if (peer->bfd_config)
bgp_peer_remove_bfd_config(peer);
/* Delete peer route flap dampening configuration. This needs to happen
* before removing the peer from peer groups.
*/
FOREACH_AFI_SAFI (afi, safi)
if (peer_af_flag_check(peer, afi, safi,
PEER_FLAG_CONFIG_DAMPENING))
bgp_peer_damp_disable(peer, afi, safi);
/* If this peer belongs to peer group, clear up the
relationship. */
if (peer->group) {
@ -3599,11 +3591,6 @@ int bgp_delete(struct bgp *bgp)
BGP_TIMER_OFF(gr_info->t_route_select);
}
/* Delete route flap dampening configuration */
FOREACH_AFI_SAFI (afi, safi) {
bgp_damp_disable(bgp, afi, safi);
}
if (BGP_DEBUG(zebra, ZEBRA)) {
if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
zlog_debug("Deleting Default VRF");

View File

@ -44,7 +44,6 @@
#include "bgp_labelpool.h"
#include "bgp_addpath_types.h"
#include "bgp_nexthop.h"
#include "bgp_damp.h"
#include "bgp_io.h"
#include "lib/bfd.h"
@ -752,9 +751,6 @@ struct bgp {
uint32_t condition_filter_count;
struct thread *t_condition_check;
/* BGP route flap dampening configuration */
struct bgp_damp_config damp[AFI_MAX][SAFI_MAX];
/* BGP VPN SRv6 backend */
bool srv6_enabled;
char srv6_locator_name[SRV6_LOCNAME_SIZE];
@ -1314,9 +1310,6 @@ struct peer {
/* Last update packet sent time */
time_t pkt_stime[AFI_MAX][SAFI_MAX];
/* Peer / peer group route flap dampening configuration */
struct bgp_damp_config damp[AFI_MAX][SAFI_MAX];
/* Peer Per AF flags */
/*
* Please consult the comments for *flags_override*, *flags_invert* and
@ -1354,8 +1347,6 @@ struct peer {
#define PEER_FLAG_SEND_LARGE_COMMUNITY (1U << 26) /* Send large Communities */
#define PEER_FLAG_MAX_PREFIX_OUT (1U << 27) /* outgoing maximum prefix */
#define PEER_FLAG_MAX_PREFIX_FORCE (1U << 28) /* maximum-prefix <num> force */
#define PEER_FLAG_CONFIG_DAMPENING (1U << 29) /* route flap dampening */
enum bgp_addpath_strat addpath_type[AFI_MAX][SAFI_MAX];