/* BGP flap dampening
- Copyright (C) 2001 IP Infusion Inc.
-
-This file is part of GNU Zebra.
-
-GNU Zebra is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
-later version.
-
-GNU Zebra is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Zebra; see the file COPYING. If not, write to the Free
-Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+ * Copyright (C) 2001 IP Infusion Inc.
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
#include <zebra.h>
#include <math.h>
/* 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) 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)
time_t t_now, t_diff;
damp->t_reuse = NULL;
- damp->t_reuse = thread_add_timer(bm->master, bgp_reuse_timer, NULL,
- DELTA_REUSE);
+ thread_add_timer(bm->master, bgp_reuse_timer, NULL, DELTA_REUSE,
+ &damp->t_reuse);
t_now = bgp_clock();
/* 3. if ( the saved list head pointer is non-empty ) */
for (; bdi; bdi = next) {
- struct bgp *bgp = bdi->binfo->peer->bgp;
+ struct bgp *bgp = bdi->path->peer->bgp;
next = bdi->next;
/* 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);
+ bgp_path_info_unset_flag(bdi->rn, bdi->path,
+ BGP_PATH_DAMPED);
bdi->suppress_time = 0;
if (bdi->lastrecord == BGP_RECORD_UPDATE) {
- bgp_info_unset_flag(bdi->rn, bdi->binfo,
- BGP_INFO_HISTORY);
+ bgp_path_info_unset_flag(bdi->rn, bdi->path,
+ BGP_PATH_HISTORY);
bgp_aggregate_increment(bgp, &bdi->rn->p,
- bdi->binfo, bdi->afi,
+ bdi->path, bdi->afi,
bdi->safi);
bgp_process(bgp, bdi->rn, bdi->afi, bdi->safi);
}
}
/* 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_path_info *path, 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;
+ unsigned int last_penalty = 0;
t_now = bgp_clock();
/* Processing Unreachable Messages. */
- if (binfo->extra)
- bdi = binfo->extra->damp_info;
+ if (path->extra)
+ bdi = path->extra->damp_info;
if (bdi == NULL) {
/* If there is no previous stability history. */
bdi = XCALLOC(MTYPE_BGP_DAMP_INFO,
sizeof(struct bgp_damp_info));
- bdi->binfo = binfo;
+ bdi->path = path;
bdi->rn = rn;
bdi->penalty =
(attr_change ? DEFAULT_PENALTY / 2 : DEFAULT_PENALTY);
bdi->index = -1;
bdi->afi = afi;
bdi->safi = safi;
- (bgp_info_extra_get(binfo))->damp_info = bdi;
+ (bgp_path_info_extra_get(path))->damp_info = bdi;
BGP_DAMP_LIST_ADD(damp, bdi);
} else {
last_penalty = bdi->penalty;
bdi->flap++;
}
- assert((rn == bdi->rn) && (binfo == bdi->binfo));
+ assert((rn == bdi->rn) && (path == bdi->path));
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);
+ bgp_path_info_set_flag(rn, path, BGP_PATH_HISTORY);
/* Remove the route from a reuse list if it is on one. */
- if (CHECK_FLAG(bdi->binfo->flags, BGP_INFO_DAMPED)) {
+ 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);
bgp_reuse_list_add(bdi);
}
/* 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);
+ 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);
return BGP_DAMP_USED;
}
-int bgp_damp_update(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
+int bgp_damp_update(struct bgp_path_info *path, 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)))
+ if (!path->extra || !((bdi = path->extra->damp_info)))
return BGP_DAMP_USED;
t_now = bgp_clock();
- bgp_info_unset_flag(rn, binfo, BGP_INFO_HISTORY);
+ 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);
- if (!CHECK_FLAG(bdi->binfo->flags, BGP_INFO_DAMPED)
+ if (!CHECK_FLAG(bdi->path->flags, BGP_PATH_DAMPED)
&& (bdi->penalty < damp->suppress_value))
status = BGP_DAMP_USED;
- else if (CHECK_FLAG(bdi->binfo->flags, BGP_INFO_DAMPED)
+ else if (CHECK_FLAG(bdi->path->flags, BGP_PATH_DAMPED)
&& (bdi->penalty < damp->reuse_limit)) {
- bgp_info_unset_flag(rn, binfo, BGP_INFO_DAMPED);
+ bgp_path_info_unset_flag(rn, path, BGP_PATH_DAMPED);
bgp_reuse_list_delete(bdi);
BGP_DAMP_LIST_ADD(damp, bdi);
bdi->suppress_time = 0;
}
/* 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_path_info *path, afi_t afi, safi_t safi)
{
time_t t_now, t_diff;
struct bgp_damp_info *bdi;
- assert(binfo->extra && binfo->extra->damp_info);
+ assert(path->extra && path->extra->damp_info);
t_now = bgp_clock();
- bdi = binfo->extra->damp_info;
+ bdi = path->extra->damp_info;
- if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)) {
+ if (CHECK_FLAG(path->flags, BGP_PATH_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_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 binfo is usable
+ /* Need to announce UPDATE once this path is usable
* again. */
if (bdi->lastrecord == BGP_RECORD_UPDATE)
return 1;
bdi->penalty = bgp_damp_decay(t_diff, bdi->penalty);
if (bdi->penalty <= damp->reuse_limit / 2.0) {
- /* release the bdi, bdi->binfo. */
+ /* release the bdi, bdi->path. */
bgp_damp_info_free(bdi, 1);
return 0;
} else
void bgp_damp_info_free(struct bgp_damp_info *bdi, int withdraw)
{
- struct bgp_info *binfo;
+ struct bgp_path_info *path;
if (!bdi)
return;
- binfo = bdi->binfo;
- binfo->extra->damp_info = NULL;
+ path = bdi->path;
+ path->extra->damp_info = NULL;
- if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED))
+ if (CHECK_FLAG(path->flags, BGP_PATH_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_path_info_unset_flag(bdi->rn, path,
+ BGP_PATH_HISTORY | BGP_PATH_DAMPED);
if (bdi->lastrecord == BGP_RECORD_WITHDRAW && withdraw)
- bgp_info_delete(bdi->rn, binfo);
+ bgp_path_info_delete(bdi->rn, path);
XFREE(MTYPE_BGP_DAMP_INFO, bdi);
}
bgp_damp_parameter_set(half, reuse, suppress, max);
/* Register reuse timer. */
- if (!damp->t_reuse)
- damp->t_reuse = thread_add_timer(bm->master, bgp_reuse_timer,
- NULL, DELTA_REUSE);
+ thread_add_timer(bm->master, bgp_reuse_timer, NULL, DELTA_REUSE,
+ &damp->t_reuse);
return 0;
}
{
/* Free decay array */
XFREE(MTYPE_BGP_DAMP_ARRAY, damp->decay_array);
+ damp->decay_array_size = 0;
/* Free reuse index array */
XFREE(MTYPE_BGP_DAMP_ARRAY, damp->reuse_index);
+ damp->reuse_index_size = 0;
/* Free reuse list array. */
XFREE(MTYPE_BGP_DAMP_ARRAY, damp->reuse_list);
+ damp->reuse_list_size = 0;
}
/* Clean all the bgp_damp_info stored in reuse_list. */
&& 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%s", VTY_NEWLINE);
+ 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%s",
- bgp_damp_cfg.half_life / 60LL, VTY_NEWLINE);
+ vty_out(vty, " bgp dampening %lld\n",
+ bgp_damp_cfg.half_life / 60LL);
else
- vty_out(vty, " bgp dampening %lld %d %d %lld%s",
+ 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_NEWLINE);
+ 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,
+ size_t len, bool use_json,
json_object *json)
{
time_t reuse_time = 0;
} else
reuse_time = 0;
-/* Making formatted timer strings. */
-#define ONE_DAY_SECOND 60*60*24
-#define ONE_WEEK_SECOND 60*60*24*7
+ /* Making formatted timer strings. */
if (reuse_time == 0) {
if (use_json)
json_object_int_add(json, "reuseTimerMsecs", 0);
return buf;
}
-void bgp_damp_info_vty(struct vty *vty, struct bgp_info *binfo,
+void bgp_damp_info_vty(struct vty *vty, struct bgp_path_info *path,
json_object *json_path)
{
struct bgp_damp_info *bdi;
char timebuf[BGP_UPTIME_LEN];
int penalty;
- if (!binfo->extra)
+ if (!path->extra)
return;
/* BGP dampening information. */
- bdi = binfo->extra->damp_info;
+ bdi = path->extra->damp_info;
/* If dampening is not enabled or there is no dampening information,
return immediately. */
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))
+ 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);
} else {
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))
+ 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(penalty, timebuf,
BGP_UPTIME_LEN, 0,
json_path));
- vty_out(vty, "%s", VTY_NEWLINE);
+ 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,
+const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_path_info *path,
+ char *timebuf, size_t len, bool use_json,
json_object *json)
{
struct bgp_damp_info *bdi;
time_t t_now, t_diff;
int penalty;
- if (!binfo->extra)
+ if (!path->extra)
return NULL;
/* BGP dampening information. */
- bdi = binfo->extra->damp_info;
+ bdi = path->extra->damp_info;
/* If dampening is not enabled or there is no dampening information,
return immediately. */
bgp = bgp_get_default();
if (bgp == NULL) {
- vty_out(vty, "No BGP process is configured%s", VTY_NEWLINE);
+ 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%s",
- (long long)damp->half_life / 60, VTY_NEWLINE);
- vty_out(vty, "Reuse penalty: %d%s", damp->reuse_limit,
- VTY_NEWLINE);
- vty_out(vty, "Suppress penalty: %d%s", damp->suppress_value,
- VTY_NEWLINE);
- vty_out(vty, "Max suppress time: %lld min%s",
- (long long)damp->max_suppress_time / 60, VTY_NEWLINE);
- vty_out(vty, "Max supress penalty: %u%s", damp->ceiling,
- VTY_NEWLINE);
- vty_out(vty, "%s", VTY_NEWLINE);
+ 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 suppress penalty: %u\n", damp->ceiling);
+ vty_out(vty, "\n");
} else
- vty_out(vty, "dampening not enabled for %s%s",
- afi == AFI_IP ? "IPv4" : "IPv6", VTY_NEWLINE);
+ vty_out(vty, "dampening not enabled for %s\n",
+ afi == AFI_IP ? "IPv4" : "IPv6");
return CMD_SUCCESS;
}