2 Copyright (C) 2001 IP Infusion Inc.
4 This file is part of GNU Zebra.
6 GNU Zebra is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 GNU Zebra is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Zebra; see the file COPYING. If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
32 #include "bgpd/bgpd.h"
33 #include "bgpd/bgp_damp.h"
34 #include "bgpd/bgp_table.h"
35 #include "bgpd/bgp_route.h"
36 #include "bgpd/bgp_attr.h"
37 #include "bgpd/bgp_advertise.h"
39 /* Global variable to access damping configuration */
40 struct bgp_damp_config bgp_damp_cfg
;
41 static struct bgp_damp_config
*damp
= &bgp_damp_cfg
;
43 /* Utility macro to add and delete BGP dampening information to no
45 #define BGP_DAMP_LIST_ADD(N,A) BGP_INFO_ADD(N,A,no_reuse_list)
46 #define BGP_DAMP_LIST_DEL(N,A) BGP_INFO_DEL(N,A,no_reuse_list)
48 /* Calculate reuse list index by penalty value. */
50 bgp_reuse_index (int penalty
)
55 i
= (int)(((double) penalty
/ damp
->reuse_limit
- 1.0) * damp
->scale_factor
);
57 if ( i
>= damp
->reuse_index_size
)
58 i
= damp
->reuse_index_size
- 1;
60 index
= damp
->reuse_index
[i
] - damp
->reuse_index
[0];
62 return (damp
->reuse_offset
+ index
) % damp
->reuse_list_size
;
65 /* Add BGP dampening information to reuse list. */
67 bgp_reuse_list_add (struct bgp_damp_info
*bdi
)
71 index
= bdi
->index
= bgp_reuse_index (bdi
->penalty
);
74 bdi
->next
= damp
->reuse_list
[index
];
75 if (damp
->reuse_list
[index
])
76 damp
->reuse_list
[index
]->prev
= bdi
;
77 damp
->reuse_list
[index
] = bdi
;
80 /* Delete BGP dampening information from reuse list. */
82 bgp_reuse_list_delete (struct bgp_damp_info
*bdi
)
85 bdi
->next
->prev
= bdi
->prev
;
87 bdi
->prev
->next
= bdi
->next
;
89 damp
->reuse_list
[bdi
->index
] = bdi
->next
;
92 /* Return decayed penalty value. */
94 bgp_damp_decay (time_t tdiff
, int penalty
)
98 i
= (int) ((double) tdiff
/ DELTA_T
);
103 if (i
>= damp
->decay_array_size
)
106 return (int) (penalty
* damp
->decay_array
[i
]);
109 /* Handler of reuse timer event. Each route in the current reuse-list
110 is evaluated. RFC2439 Section 4.8.7. */
112 bgp_reuse_timer (struct thread
*t
)
114 struct bgp_damp_info
*bdi
;
115 struct bgp_damp_info
*next
;
116 time_t t_now
, t_diff
;
118 damp
->t_reuse
= NULL
;
120 thread_add_timer (bm
->master
, bgp_reuse_timer
, NULL
, DELTA_REUSE
);
122 t_now
= bgp_clock ();
124 /* 1. save a pointer to the current zeroth queue head and zero the
126 bdi
= damp
->reuse_list
[damp
->reuse_offset
];
127 damp
->reuse_list
[damp
->reuse_offset
] = NULL
;
129 /* 2. set offset = modulo reuse-list-size ( offset + 1 ), thereby
130 rotating the circular queue of list-heads. */
131 damp
->reuse_offset
= (damp
->reuse_offset
+ 1) % damp
->reuse_list_size
;
133 /* 3. if ( the saved list head pointer is non-empty ) */
134 for (; bdi
; bdi
= next
)
136 struct bgp
*bgp
= bdi
->binfo
->peer
->bgp
;
140 /* Set t-diff = t-now - t-updated. */
141 t_diff
= t_now
- bdi
->t_updated
;
143 /* Set figure-of-merit = figure-of-merit * decay-array-ok [t-diff] */
144 bdi
->penalty
= bgp_damp_decay (t_diff
, bdi
->penalty
);
146 /* Set t-updated = t-now. */
147 bdi
->t_updated
= t_now
;
149 /* if (figure-of-merit < reuse). */
150 if (bdi
->penalty
< damp
->reuse_limit
)
152 /* Reuse the route. */
153 bgp_info_unset_flag (bdi
->rn
, bdi
->binfo
, BGP_INFO_DAMPED
);
154 bdi
->suppress_time
= 0;
156 if (bdi
->lastrecord
== BGP_RECORD_UPDATE
)
158 bgp_info_unset_flag (bdi
->rn
, bdi
->binfo
, BGP_INFO_HISTORY
);
159 bgp_aggregate_increment (bgp
, &bdi
->rn
->p
, bdi
->binfo
,
160 bdi
->afi
, bdi
->safi
);
161 bgp_process (bgp
, bdi
->rn
, bdi
->afi
, bdi
->safi
);
164 if (bdi
->penalty
<= damp
->reuse_limit
/ 2.0)
165 bgp_damp_info_free (bdi
, 1);
167 BGP_DAMP_LIST_ADD (damp
, bdi
);
170 /* Re-insert into another list (See RFC2439 Section 4.8.6). */
171 bgp_reuse_list_add (bdi
);
177 /* A route becomes unreachable (RFC2439 Section 4.8.2). */
179 bgp_damp_withdraw (struct bgp_info
*binfo
, struct bgp_node
*rn
,
180 afi_t afi
, safi_t safi
, int attr_change
)
183 struct bgp_damp_info
*bdi
= NULL
;
184 double last_penalty
= 0;
186 t_now
= bgp_clock ();
188 /* Processing Unreachable Messages. */
190 bdi
= binfo
->extra
->damp_info
;
194 /* If there is no previous stability history. */
197 1. allocate a damping structure.
198 2. set figure-of-merit = 1.
199 3. withdraw the route. */
201 bdi
= XCALLOC (MTYPE_BGP_DAMP_INFO
, sizeof (struct bgp_damp_info
));
204 bdi
->penalty
= (attr_change
? DEFAULT_PENALTY
/ 2 : DEFAULT_PENALTY
);
206 bdi
->start_time
= t_now
;
207 bdi
->suppress_time
= 0;
211 (bgp_info_extra_get (binfo
))->damp_info
= bdi
;
212 BGP_DAMP_LIST_ADD (damp
, bdi
);
216 last_penalty
= bdi
->penalty
;
218 /* 1. Set t-diff = t-now - t-updated. */
220 (bgp_damp_decay (t_now
- bdi
->t_updated
, bdi
->penalty
)
221 + (attr_change
? DEFAULT_PENALTY
/ 2 : DEFAULT_PENALTY
));
223 if (bdi
->penalty
> damp
->ceiling
)
224 bdi
->penalty
= damp
->ceiling
;
229 assert ((rn
== bdi
->rn
) && (binfo
== bdi
->binfo
));
231 bdi
->lastrecord
= BGP_RECORD_WITHDRAW
;
232 bdi
->t_updated
= t_now
;
234 /* Make this route as historical status. */
235 bgp_info_set_flag (rn
, binfo
, BGP_INFO_HISTORY
);
237 /* Remove the route from a reuse list if it is on one. */
238 if (CHECK_FLAG (bdi
->binfo
->flags
, BGP_INFO_DAMPED
))
240 /* If decay rate isn't equal to 0, reinsert brn. */
241 if (bdi
->penalty
!= last_penalty
)
243 bgp_reuse_list_delete (bdi
);
244 bgp_reuse_list_add (bdi
);
246 return BGP_DAMP_SUPPRESSED
;
249 /* If not suppressed before, do annonunce this withdraw and
250 insert into reuse_list. */
251 if (bdi
->penalty
>= damp
->suppress_value
)
253 bgp_info_set_flag (rn
, binfo
, BGP_INFO_DAMPED
);
254 bdi
->suppress_time
= t_now
;
255 BGP_DAMP_LIST_DEL (damp
, bdi
);
256 bgp_reuse_list_add (bdi
);
259 return BGP_DAMP_USED
;
263 bgp_damp_update (struct bgp_info
*binfo
, struct bgp_node
*rn
,
264 afi_t afi
, safi_t safi
)
267 struct bgp_damp_info
*bdi
;
270 if (!binfo
->extra
|| !((bdi
= binfo
->extra
->damp_info
)))
271 return BGP_DAMP_USED
;
273 t_now
= bgp_clock ();
274 bgp_info_unset_flag (rn
, binfo
, BGP_INFO_HISTORY
);
276 bdi
->lastrecord
= BGP_RECORD_UPDATE
;
277 bdi
->penalty
= bgp_damp_decay (t_now
- bdi
->t_updated
, bdi
->penalty
);
279 if (! CHECK_FLAG (bdi
->binfo
->flags
, BGP_INFO_DAMPED
)
280 && (bdi
->penalty
< damp
->suppress_value
))
281 status
= BGP_DAMP_USED
;
282 else if (CHECK_FLAG (bdi
->binfo
->flags
, BGP_INFO_DAMPED
)
283 && (bdi
->penalty
< damp
->reuse_limit
) )
285 bgp_info_unset_flag (rn
, binfo
, BGP_INFO_DAMPED
);
286 bgp_reuse_list_delete (bdi
);
287 BGP_DAMP_LIST_ADD (damp
, bdi
);
288 bdi
->suppress_time
= 0;
289 status
= BGP_DAMP_USED
;
292 status
= BGP_DAMP_SUPPRESSED
;
294 if (bdi
->penalty
> damp
->reuse_limit
/ 2.0)
295 bdi
->t_updated
= t_now
;
297 bgp_damp_info_free (bdi
, 0);
302 /* Remove dampening information and history route. */
304 bgp_damp_scan (struct bgp_info
*binfo
, afi_t afi
, safi_t safi
)
306 time_t t_now
, t_diff
;
307 struct bgp_damp_info
*bdi
;
309 assert (binfo
->extra
&& binfo
->extra
->damp_info
);
311 t_now
= bgp_clock ();
312 bdi
= binfo
->extra
->damp_info
;
314 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
316 t_diff
= t_now
- bdi
->suppress_time
;
318 if (t_diff
>= damp
->max_suppress_time
)
320 bgp_info_unset_flag (bdi
->rn
, binfo
, BGP_INFO_DAMPED
);
321 bgp_reuse_list_delete (bdi
);
322 BGP_DAMP_LIST_ADD (damp
, bdi
);
323 bdi
->penalty
= damp
->reuse_limit
;
324 bdi
->suppress_time
= 0;
325 bdi
->t_updated
= t_now
;
327 /* Need to announce UPDATE once this binfo is usable again. */
328 if (bdi
->lastrecord
== BGP_RECORD_UPDATE
)
336 t_diff
= t_now
- bdi
->t_updated
;
337 bdi
->penalty
= bgp_damp_decay (t_diff
, bdi
->penalty
);
339 if (bdi
->penalty
<= damp
->reuse_limit
/ 2.0)
341 /* release the bdi, bdi->binfo. */
342 bgp_damp_info_free (bdi
, 1);
346 bdi
->t_updated
= t_now
;
352 bgp_damp_info_free (struct bgp_damp_info
*bdi
, int withdraw
)
354 struct bgp_info
*binfo
;
360 binfo
->extra
->damp_info
= NULL
;
362 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
))
363 bgp_reuse_list_delete (bdi
);
365 BGP_DAMP_LIST_DEL (damp
, bdi
);
367 bgp_info_unset_flag (bdi
->rn
, binfo
, BGP_INFO_HISTORY
|BGP_INFO_DAMPED
);
369 if (bdi
->lastrecord
== BGP_RECORD_WITHDRAW
&& withdraw
)
370 bgp_info_delete (bdi
->rn
, binfo
);
372 XFREE (MTYPE_BGP_DAMP_INFO
, bdi
);
376 bgp_damp_parameter_set (int hlife
, int reuse
, int sup
, int maxsup
)
378 double reuse_max_ratio
;
382 damp
->suppress_value
= sup
;
383 damp
->half_life
= hlife
;
384 damp
->reuse_limit
= reuse
;
385 damp
->max_suppress_time
= maxsup
;
387 /* Initialize params per bgp_damp_config. */
388 damp
->reuse_index_size
= REUSE_ARRAY_SIZE
;
390 damp
->ceiling
= (int)(damp
->reuse_limit
* (pow(2, (double)damp
->max_suppress_time
/damp
->half_life
)));
392 /* Decay-array computations */
393 damp
->decay_array_size
= ceil ((double) damp
->max_suppress_time
/ DELTA_T
);
394 damp
->decay_array
= XMALLOC (MTYPE_BGP_DAMP_ARRAY
,
395 sizeof(double) * (damp
->decay_array_size
));
396 damp
->decay_array
[0] = 1.0;
397 damp
->decay_array
[1] = exp ((1.0/((double)damp
->half_life
/DELTA_T
)) * log(0.5));
399 /* Calculate decay values for all possible times */
400 for (i
= 2; i
< damp
->decay_array_size
; i
++)
401 damp
->decay_array
[i
] = damp
->decay_array
[i
-1] * damp
->decay_array
[1];
403 /* Reuse-list computations */
404 i
= ceil ((double)damp
->max_suppress_time
/ DELTA_REUSE
) + 1;
405 if (i
> REUSE_LIST_SIZE
|| i
== 0)
407 damp
->reuse_list_size
= i
;
409 damp
->reuse_list
= XCALLOC (MTYPE_BGP_DAMP_ARRAY
,
410 damp
->reuse_list_size
411 * sizeof (struct bgp_reuse_node
*));
413 /* Reuse-array computations */
414 damp
->reuse_index
= XCALLOC (MTYPE_BGP_DAMP_ARRAY
,
415 sizeof(int) * damp
->reuse_index_size
);
417 reuse_max_ratio
= (double)damp
->ceiling
/damp
->reuse_limit
;
418 j
= (exp((double)damp
->max_suppress_time
/damp
->half_life
) * log10(2.0));
419 if ( reuse_max_ratio
> j
&& j
!= 0 )
422 damp
->scale_factor
= (double)damp
->reuse_index_size
/(reuse_max_ratio
- 1);
424 for (i
= 0; i
< damp
->reuse_index_size
; i
++)
426 damp
->reuse_index
[i
] =
427 (int)(((double)damp
->half_life
/ DELTA_REUSE
)
428 * log10 (1.0 / (damp
->reuse_limit
* ( 1.0 + ((double)i
/damp
->scale_factor
)))) / log10(0.5));
433 bgp_damp_enable (struct bgp
*bgp
, afi_t afi
, safi_t safi
, time_t half
,
434 unsigned int reuse
, unsigned int suppress
, time_t max
)
436 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
))
438 if (damp
->half_life
== half
439 && damp
->reuse_limit
== reuse
440 && damp
->suppress_value
== suppress
441 && damp
->max_suppress_time
== max
)
443 bgp_damp_disable (bgp
, afi
, safi
);
446 SET_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
);
447 bgp_damp_parameter_set (half
, reuse
, suppress
, max
);
449 /* Register reuse timer. */
452 thread_add_timer (bm
->master
, bgp_reuse_timer
, NULL
, DELTA_REUSE
);
458 bgp_damp_config_clean (struct bgp_damp_config
*damp
)
460 /* Free decay array */
461 XFREE (MTYPE_BGP_DAMP_ARRAY
, damp
->decay_array
);
463 /* Free reuse index array */
464 XFREE (MTYPE_BGP_DAMP_ARRAY
, damp
->reuse_index
);
466 /* Free reuse list array. */
467 XFREE (MTYPE_BGP_DAMP_ARRAY
, damp
->reuse_list
);
470 /* Clean all the bgp_damp_info stored in reuse_list. */
472 bgp_damp_info_clean (void)
475 struct bgp_damp_info
*bdi
, *next
;
477 damp
->reuse_offset
= 0;
479 for (i
= 0; i
< damp
->reuse_list_size
; i
++)
481 if (! damp
->reuse_list
[i
])
484 for (bdi
= damp
->reuse_list
[i
]; bdi
; bdi
= next
)
487 bgp_damp_info_free (bdi
, 1);
489 damp
->reuse_list
[i
] = NULL
;
492 for (bdi
= damp
->no_reuse_list
; bdi
; bdi
= next
)
495 bgp_damp_info_free (bdi
, 1);
497 damp
->no_reuse_list
= NULL
;
501 bgp_damp_disable (struct bgp
*bgp
, afi_t afi
, safi_t safi
)
503 /* If it wasn't enabled, there's nothing to do. */
504 if (! CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
))
507 /* Cancel reuse thread. */
509 thread_cancel (damp
->t_reuse
);
510 damp
->t_reuse
= NULL
;
512 /* Clean BGP dampening information. */
513 bgp_damp_info_clean ();
515 /* Clear configuration */
516 bgp_damp_config_clean (&bgp_damp_cfg
);
518 UNSET_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
);
523 bgp_config_write_damp (struct vty
*vty
)
525 if (bgp_damp_cfg
.half_life
== DEFAULT_HALF_LIFE
*60
526 && bgp_damp_cfg
.reuse_limit
== DEFAULT_REUSE
527 && bgp_damp_cfg
.suppress_value
== DEFAULT_SUPPRESS
528 && bgp_damp_cfg
.max_suppress_time
== bgp_damp_cfg
.half_life
*4)
529 vty_out (vty
, " bgp dampening%s", VTY_NEWLINE
);
530 else if (bgp_damp_cfg
.half_life
!= DEFAULT_HALF_LIFE
*60
531 && bgp_damp_cfg
.reuse_limit
== DEFAULT_REUSE
532 && bgp_damp_cfg
.suppress_value
== DEFAULT_SUPPRESS
533 && bgp_damp_cfg
.max_suppress_time
== bgp_damp_cfg
.half_life
*4)
534 vty_out (vty
, " bgp dampening %lld%s",
535 bgp_damp_cfg
.half_life
/60LL,
538 vty_out (vty
, " bgp dampening %lld %d %d %lld%s",
539 bgp_damp_cfg
.half_life
/60LL,
540 bgp_damp_cfg
.reuse_limit
,
541 bgp_damp_cfg
.suppress_value
,
542 bgp_damp_cfg
.max_suppress_time
/60LL,
547 bgp_get_reuse_time (unsigned int penalty
, char *buf
, size_t len
, u_char use_json
, json_object
*json
)
549 time_t reuse_time
= 0;
550 struct tm
*tm
= NULL
;
553 if (penalty
> damp
->reuse_limit
)
555 reuse_time
= (int) (DELTA_T
* ((log((double)damp
->reuse_limit
/penalty
))/(log(damp
->decay_array
[1]))));
557 if (reuse_time
> damp
->max_suppress_time
)
558 reuse_time
= damp
->max_suppress_time
;
560 tm
= gmtime (&reuse_time
);
565 /* Making formatted timer strings. */
566 #define ONE_DAY_SECOND 60*60*24
567 #define ONE_WEEK_SECOND 60*60*24*7
571 json_object_int_add(json
, "reuseTimerMsecs", 0);
573 snprintf (buf
, len
, "00:00:00");
575 else if (reuse_time
< ONE_DAY_SECOND
)
579 time_store
= (3600000 * tm
->tm_hour
) + (60000 * tm
->tm_min
) + (1000 * tm
->tm_sec
);
580 json_object_int_add(json
, "reuseTimerMsecs", time_store
);
583 snprintf (buf
, len
, "%02d:%02d:%02d",
584 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
586 else if (reuse_time
< ONE_WEEK_SECOND
)
590 time_store
= (86400000 * tm
->tm_yday
) + (3600000 * tm
->tm_hour
) + (60000 * tm
->tm_min
) + (1000 * tm
->tm_sec
);
591 json_object_int_add(json
, "reuseTimerMsecs", time_store
);
594 snprintf (buf
, len
, "%dd%02dh%02dm",
595 tm
->tm_yday
, tm
->tm_hour
, tm
->tm_min
);
601 time_store
= (604800000 * tm
->tm_yday
/7) + (86400000 * (tm
->tm_yday
- ((tm
->tm_yday
/7) * 7))) + (3600000 * tm
->tm_hour
) + (60000 * tm
->tm_min
) + (1000 * tm
->tm_sec
);
602 json_object_int_add(json
, "reuseTimerMsecs", time_store
);
605 snprintf (buf
, len
, "%02dw%dd%02dh",
606 tm
->tm_yday
/7, tm
->tm_yday
- ((tm
->tm_yday
/7) * 7), tm
->tm_hour
);
613 bgp_damp_info_vty (struct vty
*vty
, struct bgp_info
*binfo
,
614 json_object
*json_path
)
616 struct bgp_damp_info
*bdi
;
617 time_t t_now
, t_diff
;
618 char timebuf
[BGP_UPTIME_LEN
];
624 /* BGP dampening information. */
625 bdi
= binfo
->extra
->damp_info
;
627 /* If dampening is not enabled or there is no dampening information,
628 return immediately. */
632 /* Calculate new penalty. */
633 t_now
= bgp_clock ();
634 t_diff
= t_now
- bdi
->t_updated
;
635 penalty
= bgp_damp_decay (t_diff
, bdi
->penalty
);
639 json_object_int_add(json_path
, "dampeningPenalty", penalty
);
640 json_object_int_add(json_path
, "dampeningFlapCount", bdi
->flap
);
641 peer_uptime (bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, 1, json_path
);
643 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
)
644 && ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
645 bgp_get_reuse_time (penalty
, timebuf
, BGP_UPTIME_LEN
, 1, json_path
);
649 vty_out (vty
, " Dampinfo: penalty %d, flapped %d times in %s",
651 peer_uptime (bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, 0, json_path
));
653 if (CHECK_FLAG (binfo
->flags
, BGP_INFO_DAMPED
)
654 && ! CHECK_FLAG (binfo
->flags
, BGP_INFO_HISTORY
))
655 vty_out (vty
, ", reuse in %s",
656 bgp_get_reuse_time (penalty
, timebuf
, BGP_UPTIME_LEN
, 0, json_path
));
658 vty_out (vty
, "%s", VTY_NEWLINE
);
663 bgp_damp_reuse_time_vty (struct vty
*vty
, struct bgp_info
*binfo
,
664 char *timebuf
, size_t len
, u_char use_json
, json_object
*json
)
666 struct bgp_damp_info
*bdi
;
667 time_t t_now
, t_diff
;
673 /* BGP dampening information. */
674 bdi
= binfo
->extra
->damp_info
;
676 /* If dampening is not enabled or there is no dampening information,
677 return immediately. */
681 /* Calculate new penalty. */
682 t_now
= bgp_clock ();
683 t_diff
= t_now
- bdi
->t_updated
;
684 penalty
= bgp_damp_decay (t_diff
, bdi
->penalty
);
686 return bgp_get_reuse_time (penalty
, timebuf
, len
, use_json
, json
);
690 bgp_show_dampening_parameters (struct vty
*vty
, afi_t afi
, safi_t safi
)
693 bgp
= bgp_get_default();
697 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
701 if (CHECK_FLAG (bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
))
703 vty_out (vty
, "Half-life time: %ld min%s",
704 damp
->half_life
/ 60, VTY_NEWLINE
);
705 vty_out (vty
, "Reuse penalty: %d%s",
706 damp
->reuse_limit
, VTY_NEWLINE
);
707 vty_out (vty
, "Suppress penalty: %d%s",
708 damp
->suppress_value
, VTY_NEWLINE
);
709 vty_out (vty
, "Max suppress time: %ld min%s",
710 damp
->max_suppress_time
/ 60, VTY_NEWLINE
);
711 vty_out (vty
, "Max supress penalty: %u%s",
712 damp
->ceiling
, VTY_NEWLINE
);
713 vty_out (vty
, "%s", VTY_NEWLINE
);
716 vty_out (vty
, "dampening not enabled for %s%s",
717 afi
== AFI_IP
? "IPv4" : "IPv6", VTY_NEWLINE
);