Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bgpd: per-neighbor dampening support #15911

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -11275,7 +11275,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 @@ -15827,9 +15827,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 @@ -15840,26 +15839,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 @@ -15873,7 +15884,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
Loading
Loading