]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_damp.c
*: remove the configuration lock from all daemons
[mirror_frr.git] / bgpd / bgp_damp.c
index 358a42a46c0c9597db2f195fdb657267003a6686..cf085e46fb1f1eaacc66d38217f85951b0d51d71 100644 (file)
@@ -1,22 +1,22 @@
 /* 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>
@@ -42,8 +42,8 @@ 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) 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)
@@ -112,8 +112,8 @@ static int bgp_reuse_timer(struct thread *t)
        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();
 
@@ -128,7 +128,7 @@ static int bgp_reuse_timer(struct thread *t)
 
        /* 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;
 
@@ -145,15 +145,15 @@ static int bgp_reuse_timer(struct thread *t)
                /* 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);
                        }
@@ -172,18 +172,18 @@ static int bgp_reuse_timer(struct thread *t)
 }
 
 /* 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. */
@@ -195,7 +195,7 @@ int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
 
                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);
@@ -205,7 +205,7 @@ int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
                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;
@@ -222,18 +222,18 @@ int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
                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);
                }
@@ -243,7 +243,7 @@ int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
        /* 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);
@@ -252,28 +252,28 @@ int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
        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;
@@ -290,28 +290,29 @@ int bgp_damp_update(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
 }
 
 /* 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;
@@ -323,7 +324,7 @@ int bgp_damp_scan(struct bgp_info *binfo, afi_t afi, safi_t safi)
                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
@@ -334,23 +335,24 @@ int bgp_damp_scan(struct bgp_info *binfo, afi_t afi, safi_t safi)
 
 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);
 }
@@ -436,9 +438,8 @@ int bgp_damp_enable(struct bgp *bgp, afi_t afi, safi_t safi, time_t half,
        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;
 }
@@ -447,12 +448,15 @@ static void bgp_damp_config_clean(struct bgp_damp_config *damp)
 {
        /* 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. */
@@ -508,23 +512,23 @@ void bgp_config_write_damp(struct vty *vty)
            && 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;
@@ -543,9 +547,7 @@ static const char *bgp_get_reuse_time(unsigned int penalty, char *buf,
        } 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);
@@ -591,7 +593,7 @@ static const char *bgp_get_reuse_time(unsigned int penalty, char *buf,
        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;
@@ -599,11 +601,11 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp_info *binfo,
        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.  */
@@ -621,8 +623,8 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp_info *binfo,
                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 {
@@ -632,30 +634,30 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp_info *binfo,
                        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.  */
@@ -676,25 +678,22 @@ int bgp_show_dampening_parameters(struct vty *vty, afi_t afi, safi_t safi)
        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;
 }