Skip to content

Commit

Permalink
Merge pull request #15911 from opensourcerouting/feature/bgpd_dampeni…
Browse files Browse the repository at this point in the history
…ng_per_neighbor

bgpd: per-neighbor dampening support
  • Loading branch information
riw777 committed May 13, 2024
2 parents b6f1b32 + bf37877 commit 2e02086
Show file tree
Hide file tree
Showing 13 changed files with 827 additions and 209 deletions.
506 changes: 361 additions & 145 deletions bgpd/bgp_damp.c

Large diffs are not rendered by default.

49 changes: 34 additions & 15 deletions bgpd/bgp_damp.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@

/* 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;

Expand All @@ -30,6 +25,9 @@ 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;

Expand All @@ -38,6 +36,8 @@ 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;
Expand All @@ -46,8 +46,12 @@ struct bgp_damp_info {

afi_t afi;
safi_t safi;

SLIST_ENTRY(bgp_damp_info) entry;
};

SLIST_HEAD(reuselist, bgp_damp_info);

/* Specified parameter set configuration. */
struct bgp_damp_config {
/* Value over which routes suppressed. */
Expand Down Expand Up @@ -84,12 +88,12 @@ struct bgp_damp_config {
int *reuse_index;

/* Reuse list array per-set based. */
struct bgp_damp_info **reuse_list;
int reuse_offset;
struct reuselist *reuse_list;
unsigned int reuse_offset;
safi_t safi;

/* All dampening information which is not on reuse list. */
struct bgp_damp_info *no_reuse_list;
struct reuselist no_reuse_list;

/* Reuse timer thread per-set base. */
struct event *t_reuse;
Expand All @@ -116,6 +120,8 @@ 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 *bgp, afi_t afi, safi_t safi, time_t half,
unsigned int reuse, unsigned int suppress,
time_t max);
Expand All @@ -124,20 +130,33 @@ 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, int withdraw,
afi_t afi, safi_t safi);
extern void bgp_damp_info_clean(afi_t afi, safi_t safi);
extern void bgp_damp_info_free(struct bgp_damp_info *bdi,
struct reuselist *list, int withdraw);
extern void bgp_damp_info_clean(struct bgp *bgp, struct bgp_damp_config *bdc,
afi_t afi, safi_t safi);
extern void bgp_damp_config_clean(struct bgp_damp_config *bdc);
extern int bgp_damp_decay(time_t tdiff, int penalty,
struct bgp_damp_config *damp);
extern void bgp_config_write_damp(struct vty *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);
struct bgp_damp_config *bdc);
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 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,
json_object *json);
extern int bgp_show_dampening_parameters(struct vty *vty, afi_t afi,
safi_t safi, uint16_t show_flags);
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 */
1 change: 1 addition & 0 deletions bgpd/bgp_memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ 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");
Expand Down
1 change: 1 addition & 0 deletions bgpd/bgp_memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ 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);
Expand Down
95 changes: 54 additions & 41 deletions bgpd/bgp_route.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,10 +249,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);

if (e->damp_info)
bgp_damp_info_free(e->damp_info, NULL, 0);
e->damp_info = NULL;
if (e->vrfleak && e->vrfleak->parent) {
struct bgp_path_info *bpi =
Expand Down Expand Up @@ -4279,14 +4278,16 @@ 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 (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;
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;
}
}
}

#ifdef ENABLE_BGP_VNC
if (safi == SAFI_MPLS_VPN) {
Expand Down Expand Up @@ -4855,10 +4856,9 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
bgp_labels_same((const mpls_label_t *)pi->extra->label,
pi->extra->num_labels, label,
num_labels)))) {
if (CHECK_FLAG(bgp->af_flags[afi][safi],
BGP_CONFIG_DAMPENING)
&& peer->sort == BGP_PEER_EBGP
&& CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
if (get_active_bdc_from_pi(pi, afi, safi) &&
peer->sort == BGP_PEER_EBGP &&
CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
if (bgp_debug_update(peer, p, NULL, 1)) {
bgp_debug_rdpfxpath2str(
afi, safi, prd, p, label,
Expand Down Expand Up @@ -4959,11 +4959,11 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);

/* Update bgp route dampening information. */
if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
&& peer->sort == BGP_PEER_EBGP) {
if (get_active_bdc_from_pi(pi, afi, safi) &&
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);
}
Expand Down Expand Up @@ -5074,8 +5074,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
#endif

/* Update bgp route dampening information. */
if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
&& peer->sort == BGP_PEER_EBGP) {
if (get_active_bdc_from_pi(pi, afi, safi) &&
peer->sort == BGP_PEER_EBGP) {
/* Now we do normal update dampening. */
ret = bgp_damp_update(pi, dest, afi, safi);
if (ret == BGP_DAMP_SUPPRESSED) {
Expand Down Expand Up @@ -11272,7 +11272,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, path, afi, safi, json_path);
bgp_damp_info_vty(vty, bgp, path, afi, safi, json_path);

/* Remote Label */
if (path->extra && bgp_is_valid_label(&path->extra->label[0])
Expand Down Expand Up @@ -15824,9 +15824,8 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
while (pi) {
if (pi->extra && pi->extra->damp_info) {
pi_temp = pi->next;
bgp_damp_info_free(
pi->extra->damp_info,
1, afi, safi);
bgp_damp_info_free(pi->extra->damp_info,
NULL, 1);
pi = pi_temp;
} else
pi = pi->next;
Expand All @@ -15837,26 +15836,38 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
}
} else {
dest = bgp_node_match(bgp->rib[afi][safi], &match);
if (dest != NULL) {
const struct prefix *dest_p = bgp_dest_get_prefix(dest);
if (!dest)
return CMD_SUCCESS;

if (!prefix_check
|| dest_p->prefixlen == match.prefixlen) {
pi = bgp_dest_get_bgp_path_info(dest);
while (pi) {
if (pi->extra && pi->extra->damp_info) {
pi_temp = pi->next;
bgp_damp_info_free(
pi->extra->damp_info,
1, afi, safi);
pi = pi_temp;
} else
pi = pi->next;
}
const struct prefix *dest_p = bgp_dest_get_prefix(dest);

if (prefix_check || dest_p->prefixlen != match.prefixlen)
return CMD_SUCCESS;

pi = bgp_dest_get_bgp_path_info(dest);
while (pi) {
if (!(pi->extra && pi->extra->damp_info)) {
pi = pi->next;
continue;
}

bgp_dest_unlock_node(dest);
pi_temp = pi->next;
struct bgp_damp_info *bdi = pi->extra->damp_info;

if (bdi->lastrecord != BGP_RECORD_UPDATE)
continue;

bgp_aggregate_increment(bgp,
bgp_dest_get_prefix(bdi->dest),
bdi->path, bdi->afi, bdi->safi);
bgp_process(bgp, bdi->dest, bdi->path, bdi->afi,
bdi->safi);

bgp_damp_info_free(pi->extra->damp_info, NULL, 1);
pi = pi_temp;
}

bgp_dest_unlock_node(dest);
}

return CMD_SUCCESS;
Expand All @@ -15870,7 +15881,9 @@ DEFUN (clear_ip_bgp_dampening,
BGP_STR
"Clear route flap dampening information\n")
{
bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_damp_info_clean(bgp, &bgp->damp[AFI_IP][SAFI_UNICAST], AFI_IP,
SAFI_UNICAST);
return CMD_SUCCESS;
}

Expand Down

0 comments on commit 2e02086

Please sign in to comment.