summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_damp.c582
-rw-r--r--bgpd/bgp_damp.h49
-rw-r--r--bgpd/bgp_fsm.c3
-rw-r--r--bgpd/bgp_memory.c1
-rw-r--r--bgpd/bgp_memory.h1
-rw-r--r--bgpd/bgp_open.c3
-rw-r--r--bgpd/bgp_route.c53
-rw-r--r--bgpd/bgp_vty.c109
-rw-r--r--bgpd/bgp_zebra.c5
-rw-r--r--bgpd/bgpd.c14
-rw-r--r--bgpd/bgpd.h9
-rw-r--r--doc/developer/conf.py7
-rw-r--r--doc/requirements.txt1
-rw-r--r--doc/user/bgp.rst58
-rw-r--r--doc/user/conf.py17
-rw-r--r--doc/user/ospf6d.rst13
-rw-r--r--doc/user/zebra.rst11
-rw-r--r--nhrpd/nhrp_vty.c2
-rw-r--r--ospf6d/ospf6_area.c15
-rw-r--r--ospfd/ospf_vty.c57
-rw-r--r--pimd/pim_ifchannel.c10
-rw-r--r--pimd/pim_rp.c5
-rw-r--r--ripd/ripd.c12
-rw-r--r--tests/topotests/bgp_features/exabgp.env53
-rw-r--r--tests/topotests/bgp_features/peer1/exa_readpipe.py19
-rw-r--r--tests/topotests/bgp_features/peer1/exabgp.cfg12
-rw-r--r--tests/topotests/bgp_features/peer2/exa_readpipe.py19
-rw-r--r--tests/topotests/bgp_features/peer2/exabgp.cfg12
-rw-r--r--tests/topotests/bgp_features/peer3/exa_readpipe.py19
-rw-r--r--tests/topotests/bgp_features/peer3/exabgp.cfg12
-rw-r--r--tests/topotests/bgp_features/peer4/exa_readpipe.py19
-rw-r--r--tests/topotests/bgp_features/peer4/exabgp.cfg12
-rw-r--r--tests/topotests/bgp_features/r1/bgp_damp_announced.json21
-rw-r--r--tests/topotests/bgp_features/r1/bgp_damp_setup.json10
-rw-r--r--tests/topotests/bgp_features/r2/bgp_damp_announced.json21
-rw-r--r--tests/topotests/bgp_features/r2/bgp_damp_withdrawn.json18
-rw-r--r--tests/topotests/bgp_features/test_bgp_features.py671
-rw-r--r--zebra/zebra_fpm.c4
-rw-r--r--zebra/zebra_routemap_nb_config.c28
39 files changed, 305 insertions, 1682 deletions
diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c
index 7ba0472d72..f46d416c3c 100644
--- a/bgpd/bgp_damp.c
+++ b/bgpd/bgp_damp.c
@@ -37,115 +37,19 @@
#include "bgpd/bgp_advertise.h"
#include "bgpd/bgp_vty.h"
-static void bgp_reuselist_add(struct reuselist *list,
- struct bgp_damp_info *info)
-{
- struct reuselist_node *new_node;
-
- assert(info);
- new_node = XCALLOC(MTYPE_BGP_DAMP_REUSELIST, sizeof(*new_node));
- new_node->info = info;
- SLIST_INSERT_HEAD(list, new_node, entry);
-}
-
-static void bgp_reuselist_del(struct reuselist *list,
- struct reuselist_node **node)
-{
- if ((*node) == NULL)
- return;
- assert(list && node && *node);
- SLIST_REMOVE(list, (*node), reuselist_node, entry);
- XFREE(MTYPE_BGP_DAMP_REUSELIST, (*node));
- *node = NULL;
-}
-
-static void bgp_reuselist_switch(struct reuselist *source,
- struct reuselist_node *node,
- struct reuselist *target)
-{
- assert(source && target && node);
- SLIST_REMOVE(source, node, reuselist_node, entry);
- SLIST_INSERT_HEAD(target, node, entry);
-}
-
-static void bgp_reuselist_free(struct reuselist *list)
-{
- struct reuselist_node *rn;
-
- assert(list);
- while ((rn = SLIST_FIRST(list)) != NULL)
- bgp_reuselist_del(list, &rn);
-}
-
-static struct reuselist_node *bgp_reuselist_find(struct reuselist *list,
- struct bgp_damp_info *info)
-{
- struct reuselist_node *rn;
-
- assert(list && info);
- SLIST_FOREACH (rn, list, entry) {
- if (rn->info == info)
- return rn;
- }
- return NULL;
-}
+/* Global variable to access damping configuration */
+static struct bgp_damp_config damp[AFI_MAX][SAFI_MAX];
-static void bgp_damp_info_unclaim(struct bgp_damp_info *bdi)
-{
- struct reuselist_node *node;
-
- assert(bdi && bdi->config);
- if (bdi->index == BGP_DAMP_NO_REUSE_LIST_INDEX) {
- node = bgp_reuselist_find(&bdi->config->no_reuse_list, bdi);
- if (node)
- bgp_reuselist_del(&bdi->config->no_reuse_list, &node);
- } else {
- node = bgp_reuselist_find(&bdi->config->reuse_list[bdi->index],
- bdi);
- if (node)
- bgp_reuselist_del(&bdi->config->reuse_list[bdi->index],
- &node);
- }
- bdi->config = NULL;
-}
-
-static void bgp_damp_info_claim(struct bgp_damp_info *bdi,
- struct bgp_damp_config *bdc)
-{
- assert(bdc && bdi);
- if (bdi->config == NULL) {
- bdi->config = bdc;
- return;
- }
- bgp_damp_info_unclaim(bdi);
- bdi->config = bdc;
- bdi->afi = bdc->afi;
- bdi->safi = bdc->safi;
-}
-
-struct bgp_damp_config *get_active_bdc_from_pi(struct bgp_path_info *pi,
- afi_t afi, safi_t safi)
-{
- if (!pi)
- return NULL;
- if (CHECK_FLAG(pi->peer->af_flags[afi][safi],
- PEER_FLAG_CONFIG_DAMPENING))
- return &pi->peer->damp[afi][safi];
- if (peer_group_active(pi->peer))
- if (CHECK_FLAG(pi->peer->group->conf->af_flags[afi][safi],
- PEER_FLAG_CONFIG_DAMPENING))
- return &pi->peer->group->conf->damp[afi][safi];
- if (CHECK_FLAG(pi->peer->bgp->af_flags[afi][safi],
- BGP_CONFIG_DAMPENING))
- return &pi->peer->bgp->damp[afi][safi];
- return NULL;
-}
+/* Utility macro to add and delete BGP dampening information to no
+ used 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, struct bgp_damp_config *bdc)
{
unsigned int i;
- unsigned int index;
+ int index;
/*
* reuse_limit can't be zero, this is for Coverity
@@ -168,38 +72,27 @@ static int bgp_reuse_index(int penalty, struct bgp_damp_config *bdc)
static void bgp_reuse_list_add(struct bgp_damp_info *bdi,
struct bgp_damp_config *bdc)
{
- bgp_damp_info_claim(bdi, bdc);
- bdi->index = bgp_reuse_index(bdi->penalty, bdc);
- bgp_reuselist_add(&bdc->reuse_list[bdi->index], bdi);
-}
+ int index;
-/* Delete BGP dampening information from reuse list. */
-static void bgp_reuse_list_delete(struct bgp_damp_info *bdi)
-{
- bgp_damp_info_unclaim(bdi);
-}
+ index = bdi->index = bgp_reuse_index(bdi->penalty, bdc);
-static void bgp_no_reuse_list_add(struct bgp_damp_info *bdi,
- struct bgp_damp_config *bdc)
-{
- bgp_damp_info_claim(bdi, bdc);
- bdi->index = BGP_DAMP_NO_REUSE_LIST_INDEX;
- bgp_reuselist_add(&bdc->no_reuse_list, bdi);
+ bdi->prev = NULL;
+ bdi->next = bdc->reuse_list[index];
+ if (bdc->reuse_list[index])
+ bdc->reuse_list[index]->prev = bdi;
+ bdc->reuse_list[index] = bdi;
}
-static void bgp_no_reuse_list_delete(struct bgp_damp_info *bdi,
- struct bgp_damp_config *bdc)
+/* Delete BGP dampening information from reuse list. */
+static void bgp_reuse_list_delete(struct bgp_damp_info *bdi,
+ struct bgp_damp_config *bdc)
{
- struct reuselist_node *rn;
-
- assert(bdc && bdi);
- if (bdi->config == NULL) {
- bgp_damp_info_unclaim(bdi);
- return;
- }
- bdi->config = NULL;
- rn = bgp_reuselist_find(&bdc->no_reuse_list, bdi);
- bgp_reuselist_del(&bdc->no_reuse_list, &rn);
+ if (bdi->next)
+ bdi->next->prev = bdi->prev;
+ if (bdi->prev)
+ bdi->prev->next = bdi->next;
+ else
+ bdc->reuse_list[bdi->index] = bdi->next;
}
/* Return decayed penalty value. */
@@ -222,34 +115,32 @@ int bgp_damp_decay(time_t tdiff, int penalty, struct bgp_damp_config *bdc)
is evaluated. RFC2439 Section 4.8.7. */
static int bgp_reuse_timer(struct thread *t)
{
- struct bgp_damp_config *bdc = THREAD_ARG(t);
struct bgp_damp_info *bdi;
- struct reuselist plist;
- struct reuselist_node *node;
- struct bgp *bgp;
+ struct bgp_damp_info *next;
time_t t_now, t_diff;
+ struct bgp_damp_config *bdc = THREAD_ARG(t);
+
+ bdc->t_reuse = NULL;
thread_add_timer(bm->master, bgp_reuse_timer, bdc, DELTA_REUSE,
&bdc->t_reuse);
t_now = bgp_clock();
- /* 1. save a pointer to the current queue head and zero the list head
- * list head entry. */
- assert(bdc->reuse_offset < bdc->reuse_list_size);
- plist = bdc->reuse_list[bdc->reuse_offset];
- node = SLIST_FIRST(&plist);
- SLIST_INIT(&bdc->reuse_list[bdc->reuse_offset]);
+ /* 1. save a pointer to the current zeroth queue head and zero the
+ list head entry. */
+ bdi = bdc->reuse_list[bdc->reuse_offset];
+ bdc->reuse_list[bdc->reuse_offset] = NULL;
/* 2. set offset = modulo reuse-list-size ( offset + 1 ), thereby
rotating the circular queue of list-heads. */
bdc->reuse_offset = (bdc->reuse_offset + 1) % bdc->reuse_list_size;
- assert(bdc->reuse_offset < bdc->reuse_list_size);
/* 3. if ( the saved list head pointer is non-empty ) */
- while ((node = SLIST_FIRST(&plist)) != NULL) {
- bdi = node->info;
- bgp = bdi->path->peer->bgp;
+ for (; bdi; bdi = next) {
+ struct bgp *bgp = bdi->path->peer->bgp;
+
+ next = bdi->next;
/* Set t-diff = t-now - t-updated. */
t_diff = t_now - bdi->t_updated;
@@ -278,27 +169,16 @@ static int bgp_reuse_timer(struct thread *t)
bdi->safi);
}
- if (bdi->penalty <= bdc->reuse_limit / 2.0) {
- bgp_damp_info_free(bdi, bdc, 1, bdi->afi,
- bdi->safi);
- bgp_reuselist_del(&plist, &node);
- } else {
- node->info->index =
- BGP_DAMP_NO_REUSE_LIST_INDEX;
- bgp_reuselist_switch(&plist, node,
- &bdc->no_reuse_list);
- }
- } else {
+ if (bdi->penalty <= bdc->reuse_limit / 2.0)
+ bgp_damp_info_free(bdi, 1, bdc->afi, bdc->safi);
+ else
+ BGP_DAMP_LIST_ADD(bdc, bdi);
+ } else
/* Re-insert into another list (See RFC2439 Section
* 4.8.6). */
- bdi->index = bgp_reuse_index(bdi->penalty, bdc);
- bgp_reuselist_switch(&plist, node,
- &bdc->reuse_list[bdi->index]);
- }
+ bgp_reuse_list_add(bdi, bdc);
}
- assert(SLIST_EMPTY(&plist));
-
return 0;
}
@@ -309,13 +189,10 @@ int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest,
time_t t_now;
struct bgp_damp_info *bdi = NULL;
unsigned int last_penalty = 0;
- struct bgp_damp_config *bdc;
-
- bdc = get_active_bdc_from_pi(path, afi, safi);
- if (!bdc)
- return BGP_DAMP_USED;
+ struct bgp_damp_config *bdc = &damp[afi][safi];
t_now = bgp_clock();
+
/* Processing Unreachable Messages. */
if (path->extra)
bdi = path->extra->damp_info;
@@ -337,20 +214,12 @@ int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest,
bdi->flap = 1;
bdi->start_time = t_now;
bdi->suppress_time = 0;
- bdi->index = BGP_DAMP_NO_REUSE_LIST_INDEX;
+ bdi->index = -1;
bdi->afi = afi;
bdi->safi = safi;
(bgp_path_info_extra_get(path))->damp_info = bdi;
- bgp_no_reuse_list_add(bdi, bdc);
+ BGP_DAMP_LIST_ADD(bdc, bdi);
} else {
- if (bdi->config != bdc) {
- bgp_damp_info_claim(bdi, bdc);
- if (bdi->index == BGP_DAMP_NO_REUSE_LIST_INDEX)
- bgp_reuselist_add(&bdc->no_reuse_list, bdi);
- else
- bgp_reuselist_add(&bdc->reuse_list[bdi->index],
- bdi);
- }
last_penalty = bdi->penalty;
/* 1. Set t-diff = t-now - t-updated. */
@@ -376,8 +245,8 @@ int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest,
/* Remove the route from a reuse list if it is on one. */
if (CHECK_FLAG(bdi->path->flags, BGP_PATH_DAMPED)) {
/* If decay rate isn't equal to 0, reinsert brn. */
- if (bdi->penalty != last_penalty) {
- bgp_reuse_list_delete(bdi);
+ if (bdi->penalty != last_penalty && bdi->index >= 0) {
+ bgp_reuse_list_delete(bdi, bdc);
bgp_reuse_list_add(bdi, bdc);
}
return BGP_DAMP_SUPPRESSED;
@@ -388,9 +257,10 @@ int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest,
if (bdi->penalty >= bdc->suppress_value) {
bgp_path_info_set_flag(dest, path, BGP_PATH_DAMPED);
bdi->suppress_time = t_now;
- bgp_no_reuse_list_delete(bdi, bdc);
+ BGP_DAMP_LIST_DEL(bdc, bdi);
bgp_reuse_list_add(bdi, bdc);
}
+
return BGP_DAMP_USED;
}
@@ -400,10 +270,7 @@ int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest,
time_t t_now;
struct bgp_damp_info *bdi;
int status;
- struct bgp_damp_config *bdc;
-
- bdc = get_active_bdc_from_pi(path, afi, safi);
- assert(bdc);
+ struct bgp_damp_config *bdc = &damp[afi][safi];
if (!path->extra || !((bdi = path->extra->damp_info)))
return BGP_DAMP_USED;
@@ -421,8 +288,8 @@ int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest,
else if (CHECK_FLAG(bdi->path->flags, BGP_PATH_DAMPED)
&& (bdi->penalty < bdc->reuse_limit)) {
bgp_path_info_unset_flag(dest, path, BGP_PATH_DAMPED);
- bgp_reuse_list_delete(bdi);
- bgp_no_reuse_list_add(bdi, bdc);
+ bgp_reuse_list_delete(bdi, bdc);
+ BGP_DAMP_LIST_ADD(bdc, bdi);
bdi->suppress_time = 0;
status = BGP_DAMP_USED;
} else
@@ -430,29 +297,36 @@ int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest,
if (bdi->penalty > bdc->reuse_limit / 2.0)
bdi->t_updated = t_now;
- else {
- bgp_damp_info_unclaim(bdi);
- bgp_damp_info_free(bdi, bdc, 0, afi, safi);
- }
+ else
+ bgp_damp_info_free(bdi, 0, afi, safi);
return status;
}
-void bgp_damp_info_free(struct bgp_damp_info *bdi, struct bgp_damp_config *bdc,
- int withdraw, afi_t afi, safi_t safi)
+void bgp_damp_info_free(struct bgp_damp_info *bdi, int withdraw, afi_t afi,
+ safi_t safi)
{
- assert(bdc && bdi);
+ struct bgp_path_info *path;
+ struct bgp_damp_config *bdc = &damp[afi][safi];
- if (bdi->path == NULL) {
- XFREE(MTYPE_BGP_DAMP_INFO, bdi);
+ if (!bdi)
return;
- }
- bdi->path->extra->damp_info = NULL;
- bgp_path_info_unset_flag(bdi->dest, bdi->path,
+ path = bdi->path;
+ path->extra->damp_info = NULL;
+
+ if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
+ bgp_reuse_list_delete(bdi, bdc);
+ else
+ BGP_DAMP_LIST_DEL(bdc, bdi);
+
+ bgp_path_info_unset_flag(bdi->dest, path,
BGP_PATH_HISTORY | BGP_PATH_DAMPED);
+
if (bdi->lastrecord == BGP_RECORD_WITHDRAW && withdraw)
- bgp_path_info_delete(bdi->dest, bdi->path);
+ bgp_path_info_delete(bdi->dest, path);
+
+ XFREE(MTYPE_BGP_DAMP_INFO, bdi);
}
static void bgp_damp_parameter_set(int hlife, int reuse, int sup, int maxsup,
@@ -495,7 +369,8 @@ static void bgp_damp_parameter_set(int hlife, int reuse, int sup, int maxsup,
bdc->reuse_list =
XCALLOC(MTYPE_BGP_DAMP_ARRAY,
- bdc->reuse_list_size * sizeof(struct reuselist));
+ bdc->reuse_list_size * sizeof(struct bgp_reuse_node *));
+
/* Reuse-array computations */
bdc->reuse_index = XCALLOC(MTYPE_BGP_DAMP_ARRAY,
sizeof(int) * bdc->reuse_index_size);
@@ -522,7 +397,7 @@ static void bgp_damp_parameter_set(int hlife, int reuse, int sup, int maxsup,
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)
{
- struct bgp_damp_config *bdc = &bgp->damp[afi][safi];
+ struct bgp_damp_config *bdc = &damp[afi][safi];
if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) {
if (bdc->half_life == half && bdc->reuse_limit == reuse
@@ -534,8 +409,6 @@ int bgp_damp_enable(struct bgp *bgp, afi_t afi, safi_t safi, time_t half,
SET_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING);
bgp_damp_parameter_set(half, reuse, suppress, max, bdc);
- bdc->afi = afi;
- bdc->safi = safi;
/* Register reuse timer. */
thread_add_timer(bm->master, bgp_reuse_timer, bdc, DELTA_REUSE,
@@ -544,38 +417,8 @@ int bgp_damp_enable(struct bgp *bgp, afi_t afi, safi_t safi, time_t half,
return 0;
}
-/* Clean all the bgp_damp_info stored in reuse_list and no_reuse_list. */
-void bgp_damp_info_clean(struct bgp *bgp, struct bgp_damp_config *bdc,
- afi_t afi, safi_t safi)
+static void bgp_damp_config_clean(struct bgp_damp_config *bdc)
{
- struct bgp_damp_info *bdi;
- struct reuselist_node *rn;
- struct reuselist *list;
- unsigned int i;
-
- bdc->reuse_offset = 0;
- for (i = 0; i < bdc->reuse_list_size; ++i) {
- list = &bdc->reuse_list[i];
- while ((rn = SLIST_FIRST(list)) != NULL) {
- bdi = rn->info;
- if (bdi->lastrecord == BGP_RECORD_UPDATE) {
- bgp_aggregate_increment(bgp, &bdi->dest->p,
- bdi->path, bdi->afi,
- bdi->safi);
- bgp_process(bgp, bdi->dest, bdi->afi,
- bdi->safi);
- }
- bgp_reuselist_del(list, &rn);
- bgp_damp_info_free(bdi, bdc, 1, afi, safi);
- }
- }
-
- while ((rn = SLIST_FIRST(&bdc->no_reuse_list)) != NULL) {
- bdi = rn->info;
- bgp_reuselist_del(&bdc->no_reuse_list, &rn);
- bgp_damp_info_free(bdi, bdc, 1, afi, safi);
- }
-
/* Free decay array */
XFREE(MTYPE_BGP_DAMP_ARRAY, bdc->decay_array);
bdc->decay_array_size = 0;
@@ -585,81 +428,96 @@ void bgp_damp_info_clean(struct bgp *bgp, struct bgp_damp_config *bdc,
bdc->reuse_index_size = 0;
/* Free reuse list array. */
- for (i = 0; i < bdc->reuse_list_size; ++i)
- bgp_reuselist_free(&bdc->reuse_list[i]);
-
XFREE(MTYPE_BGP_DAMP_ARRAY, bdc->reuse_list);
bdc->reuse_list_size = 0;
-
- THREAD_OFF(bdc->t_reuse);
}
-/* Disable route flap dampening for a bgp instance.
- *
- * Please note that this function also gets used to free memory when deleting a
- * bgp instance.
- */
-int bgp_damp_disable(struct bgp *bgp, afi_t afi, safi_t safi)
+/* Clean all the bgp_damp_info stored in reuse_list. */
+void bgp_damp_info_clean(afi_t afi, safi_t safi)
{
- struct bgp_damp_config *bdc;
+ unsigned int i;
+ struct bgp_damp_info *bdi, *next;
+ struct bgp_damp_config *bdc = &damp[afi][safi];
- bdc = &bgp->damp[afi][safi];
- if (!bdc)
- return 0;
+ bdc->reuse_offset = 0;
+
+ for (i = 0; i < bdc->reuse_list_size; i++) {
+ if (!bdc->reuse_list[i])
+ continue;
+ for (bdi = bdc->reuse_list[i]; bdi; bdi = next) {
+ next = bdi->next;
+ bgp_damp_info_free(bdi, 1, afi, safi);
+ }
+ bdc->reuse_list[i] = NULL;
+ }
+
+ for (bdi = bdc->no_reuse_list; bdi; bdi = next) {
+ next = bdi->next;
+ bgp_damp_info_free(bdi, 1, afi, safi);
+ }
+ bdc->no_reuse_list = NULL;
+}
+
+int bgp_damp_disable(struct bgp *bgp, afi_t afi, safi_t safi)
+{
+ struct bgp_damp_config *bdc = &damp[afi][safi];
/* If it wasn't enabled, there's nothing to do. */
if (!CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING))
return 0;
/* Cancel reuse event. */
- thread_cancel(&bdc->t_reuse);
+ thread_cancel(&(bdc->t_reuse));
/* Clean BGP dampening information. */
- bgp_damp_info_clean(bgp, bdc, afi, safi);
+ bgp_damp_info_clean(afi, safi);
- UNSET_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING);
+ /* Clear configuration */
+ bgp_damp_config_clean(bdc);
+ UNSET_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING);
return 0;
}
-void bgp_config_write_damp(struct vty *vty, struct bgp *bgp, afi_t afi,
- safi_t safi)
+void bgp_config_write_damp(struct vty *vty, afi_t afi, safi_t safi)
{
- struct bgp_damp_config *bdc;
-
- bdc = &bgp->damp[afi][safi];
- if (bdc->half_life == DEFAULT_HALF_LIFE * 60
- && bdc->reuse_limit == DEFAULT_REUSE
- && bdc->suppress_value == DEFAULT_SUPPRESS
- && bdc->max_suppress_time == bdc->half_life * 4)
+ if (damp[afi][safi].half_life == DEFAULT_HALF_LIFE * 60
+ && damp[afi][safi].reuse_limit == DEFAULT_REUSE
+ && damp[afi][safi].suppress_value == DEFAULT_SUPPRESS
+ && damp[afi][safi].max_suppress_time
+ == damp[afi][safi].half_life * 4)
vty_out(vty, " bgp dampening\n");
- else if (bdc->half_life != DEFAULT_HALF_LIFE * 60
- && bdc->reuse_limit == DEFAULT_REUSE
- && bdc->suppress_value == DEFAULT_SUPPRESS
- && bdc->max_suppress_time == bdc->half_life * 4)
- vty_out(vty, " bgp dampening %lld\n", bdc->half_life / 60LL);
+ else if (damp[afi][safi].half_life != DEFAULT_HALF_LIFE * 60
+ && damp[afi][safi].reuse_limit == DEFAULT_REUSE
+ && damp[afi][safi].suppress_value == DEFAULT_SUPPRESS
+ && damp[afi][safi].max_suppress_time
+ == damp[afi][safi].half_life * 4)
+ vty_out(vty, " bgp dampening %lld\n",
+ damp[afi][safi].half_life / 60LL);
else
vty_out(vty, " bgp dampening %lld %d %d %lld\n",
- bdc->half_life / 60LL, bdc->reuse_limit,
- bdc->suppress_value, bdc->max_suppress_time / 60LL);
+ damp[afi][safi].half_life / 60LL,
+ damp[afi][safi].reuse_limit,
+ damp[afi][safi].suppress_value,
+ damp[afi][safi].max_suppress_time / 60LL);
}
-static const char *bgp_get_reuse_time(struct bgp_damp_config *bdc,
- unsigned int penalty, char *buf,
- size_t len, bool use_json,
- json_object *json)
+static const char *bgp_get_reuse_time(unsigned int penalty, char *buf,
+ size_t len, afi_t afi, safi_t safi,
+ bool use_json, json_object *json)
{
time_t reuse_time = 0;
struct tm tm;
int time_store = 0;
- if (penalty > bdc->reuse_limit) {
+ if (penalty > damp[afi][safi].reuse_limit) {
reuse_time = (int)(DELTA_T
- * ((log((double)bdc->reuse_limit / penalty))
- / (log(bdc->decay_array[1]))));
+ * ((log((double)damp[afi][safi].reuse_limit
+ / penalty))
+ / (log(damp[afi][safi].decay_array[1]))));
- if (reuse_time > bdc->max_suppress_time)
- reuse_time = bdc->max_suppress_time;
+ if (reuse_time > damp[afi][safi].max_suppress_time)
+ reuse_time = damp[afi][safi].max_suppress_time;
gmtime_r(&reuse_time, &tm);
} else
@@ -711,15 +569,14 @@ static const char *bgp_get_reuse_time(struct bgp_damp_config *bdc,
return buf;
}
-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)
+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_info *bdi;
time_t t_now, t_diff;
char timebuf[BGP_UPTIME_LEN];
int penalty;
- struct bgp_damp_config *bdc = &bgp->damp[afi][safi];
+ struct bgp_damp_config *bdc = &damp[afi][safi];
if (!path->extra)
return;
@@ -745,8 +602,8 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp *bgp,
if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
&& !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
- bgp_get_reuse_time(bdc, penalty, timebuf,
- BGP_UPTIME_LEN, 1, json_path);
+ bgp_get_reuse_time(penalty, timebuf, BGP_UPTIME_LEN,
+ afi, safi, 1, json_path);
} else {
vty_out(vty,
" Dampinfo: penalty %d, flapped %d times in %s",
@@ -757,15 +614,14 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp *bgp,
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(bdc, penalty, timebuf,
- BGP_UPTIME_LEN, 0,
+ bgp_get_reuse_time(penalty, timebuf,
+ BGP_UPTIME_LEN, afi, safi, 0,
json_path));
vty_out(vty, "\n");
}
}
-
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,
@@ -774,11 +630,7 @@ const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_path_info *path,
struct bgp_damp_info *bdi;
time_t t_now, t_diff;
int penalty;
- struct bgp_damp_config *bdc;
-
- bdc = get_active_bdc_from_pi(path, afi, safi);
- if (!bdc)
- return NULL;
+ struct bgp_damp_config *bdc = &damp[afi][safi];
if (!path->extra)
return NULL;
@@ -796,23 +648,24 @@ const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_path_info *path,
t_diff = t_now - bdi->t_updated;
penalty = bgp_damp_decay(t_diff, bdi->penalty, bdc);
- return bgp_get_reuse_time(bdc, penalty, timebuf, len, use_json, json);
+ return bgp_get_reuse_time(penalty, timebuf, len, afi, safi, use_json,
+ json);
}
-
static int bgp_print_dampening_parameters(struct bgp *bgp, struct vty *vty,
afi_t afi, safi_t safi)
{
- struct bgp_damp_config *bdc;
if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) {
- bdc = &bgp->damp[afi][safi];
vty_out(vty, "Half-life time: %lld min\n",
- (long long)bdc->half_life / 60);
- vty_out(vty, "Reuse penalty: %d\n", bdc->reuse_limit);
- vty_out(vty, "Suppress penalty: %d\n", bdc->suppress_value);
+ (long long)damp[afi][safi].half_life / 60);
+ vty_out(vty, "Reuse penalty: %d\n",
+ damp[afi][safi].reuse_limit);
+ vty_out(vty, "Suppress penalty: %d\n",
+ damp[afi][safi].suppress_value);
vty_out(vty, "Max suppress time: %lld min\n",
- (long long)bdc->max_suppress_time / 60);
- vty_out(vty, "Max suppress penalty: %u\n", bdc->ceiling);
+ (long long)damp[afi][safi].max_suppress_time / 60);
+ vty_out(vty, "Max suppress penalty: %u\n",
+ damp[afi][safi].ceiling);
vty_out(vty, "\n");
} else
vty_out(vty, "dampening not enabled for %s\n",
@@ -825,8 +678,8 @@ int bgp_show_dampening_parameters(struct vty *vty, afi_t afi, safi_t safi,
uint8_t show_flags)
{
struct bgp *bgp;
-
bgp = bgp_get_default();
+
if (bgp == NULL) {
vty_out(vty, "No BGP process is configured\n");
return CMD_WARNING;
@@ -865,132 +718,3 @@ int bgp_show_dampening_parameters(struct vty *vty, afi_t afi, safi_t safi,
}
return CMD_SUCCESS;
}
-
-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)
-{
- struct bgp_damp_config *bdc;
-
- if (!peer)
- return;
- bdc = &peer->damp[afi][safi];
- if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_CONFIG_DAMPENING)) {
- if (bdc->half_life == half && bdc->reuse_limit == reuse
- && bdc->suppress_value == suppress
- && bdc->max_suppress_time == max)
- return;
- bgp_peer_damp_disable(peer, afi, safi);
- }
- SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_CONFIG_DAMPENING);
- bgp_damp_parameter_set(half, reuse, suppress, max, bdc);
- bdc->afi = afi;
- bdc->safi = safi;
- thread_add_timer(bm->master, bgp_reuse_timer, bdc, DELTA_REUSE,
- &bdc->t_reuse);
-}
-
-/* Disable route flap dampening for a peer.
- *
- * Please note that this function also gets used to free memory when deleting a
- * peer or peer group.
- */
-void bgp_peer_damp_disable(struct peer *peer, afi_t afi, safi_t safi)
-{
- struct bgp_damp_config *bdc;
-
- if (!peer_af_flag_check(peer, afi, safi, PEER_FLAG_CONFIG_DAMPENING))
- return;
- bdc = &peer->damp[afi][safi];
- if (!bdc)
- return;
- bgp_damp_info_clean(peer->bgp, bdc, afi, safi);
- UNSET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_CONFIG_DAMPENING);
-}
-
-void bgp_config_write_peer_damp(struct vty *vty, struct peer *peer, afi_t afi,
- safi_t safi)
-{
- struct bgp_damp_config *bdc;
-
- bdc = &peer->damp[afi][safi];
- if (bdc->half_life == DEFAULT_HALF_LIFE * 60
- && bdc->reuse_limit == DEFAULT_REUSE
- && bdc->suppress_value == DEFAULT_SUPPRESS
- && bdc->max_suppress_time == bdc->half_life * 4)
- vty_out(vty, " neighbor %s dampening\n", peer->host);
- else if (bdc->half_life != DEFAULT_HALF_LIFE * 60
- && bdc->reuse_limit == DEFAULT_REUSE
- && bdc->suppress_value == DEFAULT_SUPPRESS
- && bdc->max_suppress_time == bdc->half_life * 4)
- vty_out(vty, " neighbor %s dampening %lld\n", peer->host,
- bdc->half_life / 60LL);
- else
- vty_out(vty, " neighbor %s dampening %lld %d %d %lld\n",
- peer->host, bdc->half_life / 60LL, bdc->reuse_limit,
- bdc->suppress_value, bdc->max_suppress_time / 60LL);
-}
-
-static void bgp_print_peer_dampening_parameters(struct vty *vty,
- struct peer *peer, afi_t afi,
- safi_t safi, bool use_json,
- json_object *json)
-{
- struct bgp_damp_config *bdc;
-
- if (!peer)
- return;
- if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_CONFIG_DAMPENING)) {
- bdc = &peer->damp[afi][safi];
- if (!bdc)
- return;
- if (use_json) {
- json_object_int_add(json, "halfLifeSecs",
- bdc->half_life);
- json_object_int_add(json, "reusePenalty",
- bdc->reuse_limit);
- json_object_int_add(json, "suppressPenalty",
- bdc->suppress_value);
- json_object_int_add(json, "maxSuppressTimeSecs",
- bdc->max_suppress_time);
- json_object_int_add(json, "maxSuppressPenalty",
- bdc->ceiling);
- } else {
- vty_out(vty, "Half-life time: %lld min\n",
- (long long)bdc->half_life / 60);
- vty_out(vty, "Reuse penalty: %d\n", bdc->reuse_limit);
- vty_out(vty, "Suppress penalty: %d\n",
- bdc->suppress_value);
- vty_out(vty, "Max suppress time: %lld min\n",
- (long long)bdc->max_suppress_time / 60);
- vty_out(vty, "Max suppress penalty: %u\n",
- bdc->ceiling);
- vty_out(vty, "\n");
- }
- } else if (!use_json)
- vty_out(vty, "neighbor dampening not enabled for %s\n",
- get_afi_safi_str(afi, safi, false));
-}
-
-void bgp_show_peer_dampening_parameters(struct vty *vty, struct peer *peer,
- afi_t afi, safi_t safi, bool use_json)
-{
- json_object *json;
-
- if (use_json) {
- json = json_object_new_object();
- json_object_string_add(json, "addressFamily",
- get_afi_safi_str(afi, safi, false));
- bgp_print_peer_dampening_parameters(vty, peer, afi, safi, true,
- json);
- vty_out(vty, "%s\n",
- json_object_to_json_string_ext(
- json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- } else {
- vty_out(vty, "\nFor address family: %s\n",
- get_afi_safi_str(afi, safi, false));
- bgp_print_peer_dampening_parameters(vty, peer, afi, safi, false,
- NULL);
- }
-}
diff --git a/bgpd/bgp_damp.h b/bgpd/bgp_damp.h
index 62b49dcb91..604706300b 100644
--- a/bgpd/bgp_damp.h
+++ b/bgpd/bgp_damp.h
@@ -25,6 +25,11 @@
/* 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;
@@ -40,9 +45,6 @@ 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;
@@ -51,8 +53,6 @@ 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;
@@ -63,13 +63,6 @@ struct bgp_damp_info {
safi_t safi;
};
-struct reuselist_node {
- SLIST_ENTRY(reuselist_node) entry;
- struct bgp_damp_info *info;
-};
-
-SLIST_HEAD(reuselist, reuselist_node);
-
/* Specified parameter set configuration. */
struct bgp_damp_config {
/* Value over which routes suppressed. */
@@ -107,11 +100,11 @@ struct bgp_damp_config {
int *reuse_index;
/* Reuse list array per-set based. */
- struct reuselist *reuse_list;
- unsigned int reuse_offset;
+ struct bgp_damp_info **reuse_list;
+ int reuse_offset;
/* All dampening information which is not on reuse list. */
- struct reuselist no_reuse_list;
+ struct bgp_damp_info *no_reuse_list;
/* Reuse timer thread per-set base. */
struct thread *t_reuse;
@@ -139,8 +132,6 @@ 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 *, afi_t, safi_t, time_t, unsigned int,
unsigned int, time_t);
extern int bgp_damp_disable(struct bgp *, afi_t, safi_t);
@@ -148,18 +139,13 @@ 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 *bdi,
- struct bgp_damp_config *bdc, int withdraw,
+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(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 void bgp_damp_info_clean(afi_t afi, safi_t safi);
extern int bgp_damp_decay(time_t, int, struct bgp_damp_config *damp);
-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 void bgp_config_write_damp(struct 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);
extern const char *bgp_damp_reuse_time_vty(struct vty *vty,
struct bgp_path_info *path,
char *timebuf, size_t len, afi_t afi,
@@ -167,14 +153,5 @@ extern const char *bgp_damp_reuse_time_vty(struct vty *vty,
json_object *json);
extern int bgp_show_dampening_parameters(struct vty *vty, afi_t, safi_t,
uint8_t);
-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 */
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index a242510566..c8aabec504 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -1378,6 +1378,9 @@ int bgp_stop(struct peer *peer)
peer->fd = -1;
}
+ /* Reset capabilities. */
+ peer->cap = 0;
+
FOREACH_AFI_SAFI (afi, safi) {
/* Reset all negotiated variables */
peer->afc_nego[afi][safi] = 0;
diff --git a/bgpd/bgp_memory.c b/bgpd/bgp_memory.c
index fc508496cc..1a35addac5 100644
--- a/bgpd/bgp_memory.c
+++ b/bgpd/bgp_memory.c
@@ -100,7 +100,6 @@ 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");
diff --git a/bgpd/bgp_memory.h b/bgpd/bgp_memory.h
index 4080248038..23e1d082a4 100644
--- a/bgpd/bgp_memory.h
+++ b/bgpd/bgp_memory.h
@@ -96,7 +96,6 @@ 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);
diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c
index 94d905127d..113017559e 100644
--- a/bgpd/bgp_open.c
+++ b/bgpd/bgp_open.c
@@ -1216,7 +1216,8 @@ int bgp_open_option_parse(struct peer *peer, uint8_t length, int *mp_capability)
/* Extended Message Support */
peer->max_packet_size =
- CHECK_FLAG(peer->cap, PEER_CAP_EXTENDED_MESSAGE_RCV)
+ (CHECK_FLAG(peer->cap, PEER_CAP_EXTENDED_MESSAGE_RCV)
+ && CHECK_FLAG(peer->cap, PEER_CAP_EXTENDED_MESSAGE_ADV))
? BGP_EXTENDED_MESSAGE_MAX_PACKET_SIZE
: BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE;
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 8bbdb05248..3490a4fa40 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -216,6 +216,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);
e->damp_info = NULL;
if (e->parent) {
@@ -3378,16 +3381,14 @@ 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 (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;
- }
+ 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;
}
- }
#ifdef ENABLE_BGP_VNC
if (safi == SAFI_MPLS_VPN) {
@@ -3856,7 +3857,8 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
&& (overlay_index_equal(
afi, pi,
evpn == NULL ? NULL : &evpn->gw_ip))) {
- if (get_active_bdc_from_pi(pi, afi, safi)
+ if (CHECK_FLAG(bgp->af_flags[afi][safi],
+ BGP_CONFIG_DAMPENING)
&& peer->sort == BGP_PEER_EBGP
&& CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
if (bgp_debug_update(peer, p, NULL, 1)) {
@@ -3950,11 +3952,11 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
bgp_aggregate_decrement(bgp, p, pi, afi, safi);
/* Update bgp route dampening information. */
- if (get_active_bdc_from_pi(pi, afi, safi)
+ if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
&& 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);
}
@@ -4077,7 +4079,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
#endif
/* Update bgp route dampening information. */
- if (get_active_bdc_from_pi(pi, afi, safi)
+ if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
&& peer->sort == BGP_PEER_EBGP) {
/* Now we do normal update dampening. */
ret = bgp_damp_update(pi, dest, afi, safi);
@@ -10207,7 +10209,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, bgp, path, afi, safi, json_path);
+ bgp_damp_info_vty(vty, path, afi, safi, json_path);
/* Remote Label */
if (path->extra && bgp_is_valid_label(&path->extra->label[0])
@@ -14359,7 +14361,6 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
pi_temp = pi->next;
bgp_damp_info_free(
pi->extra->damp_info,
- &bgp->damp[afi][safi],
1, afi, safi);
pi = pi_temp;
} else
@@ -14380,24 +14381,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;
- struct bgp_damp_info *bdi =
- pi->extra->damp_info;
- if (bdi->lastrecord
- == BGP_RECORD_UPDATE) {
- bgp_aggregate_increment(
- bgp,
- &bdi->dest->p,
- bdi->path,
- bdi->afi,
- bdi->safi);
- bgp_process(bgp,
- bdi->dest,
- bdi->afi,
- bdi->safi);
- }
bgp_damp_info_free(
pi->extra->damp_info,
- &bgp->damp[afi][safi],
1, afi, safi);
pi = pi_temp;
} else
@@ -14420,9 +14405,7 @@ DEFUN (clear_ip_bgp_dampening,
BGP_STR
"Clear route flap dampening information\n")
{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_damp_info_clean(bgp, &bgp->damp[AFI_IP][SAFI_UNICAST], AFI_IP,
- SAFI_UNICAST);
+ bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
return CMD_SUCCESS;
}
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 824b326e90..ea0e0a5823 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -7948,93 +7948,6 @@ DEFPY(
return CMD_SUCCESS;
}
-DEFPY(neighbor_damp,
- neighbor_damp_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor dampening [(1-45)$half [(1-20000)$reuse (1-20000)$suppress (1-255)$max]]",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Enable neighbor route-flap dampening\n"
- "Half-life time for the penalty\n"
- "Value to start reusing a route\n"
- "Value to start suppressing a route\n"
- "Maximum duration to suppress a stable route\n")
-{
- struct peer *peer = peer_and_group_lookup_vty(vty, neighbor);
-
- if (!peer)
- return CMD_WARNING_CONFIG_FAILED;
- if (!half)
- half = DEFAULT_HALF_LIFE;
- if (!reuse) {
- reuse = DEFAULT_REUSE;
- suppress = DEFAULT_SUPPRESS;
- max = half * 4;
- }
- if (suppress < reuse) {
- vty_out(vty,
- "Suppress value cannot be less than reuse value\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- bgp_peer_damp_enable(peer, bgp_node_afi(vty), bgp_node_safi(vty),
- half * 60, reuse, suppress, max * 60);
- return CMD_SUCCESS;
-}
-
-DEFPY(no_neighbor_damp,
- no_neighbor_damp_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor dampening [HALF [REUSE SUPPRESS MAX]]",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Enable neighbor route-flap dampening\n"
- "Half-life time for the penalty\n"
- "Value to start reusing a route\n"
- "Value to start suppressing a route\n"
- "Maximum duration to suppress a stable route\n")
-{
- struct peer *peer = peer_and_group_lookup_vty(vty, neighbor);
-
- if (!peer)
- return CMD_WARNING_CONFIG_FAILED;
- bgp_peer_damp_disable(peer, bgp_node_afi(vty), bgp_node_safi(vty));
- return CMD_SUCCESS;
-}
-
-DEFPY (show_ip_bgp_neighbor_damp_param,
- show_ip_bgp_neighbor_damp_param_cmd,
- "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD>$neighbor dampening parameters [json]$json",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_AFI_HELP_STR
- "Address Family modifier\n"
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Neighbor route-flap dampening information\n"
- "Display detail of configured dampening parameters\n"
- JSON_STR)
-{
- bool use_json = false;
- int idx = 0;
- afi_t afi = AFI_IP;
- safi_t safi = SAFI_UNICAST;
- struct peer *peer;
-
- if (argv_find(argv, argc, "ip", &idx))
- afi = AFI_IP;
- if (argv_find(argv, argc, "ipv4", &idx))
- afi = AFI_IP;
- if (argv_find(argv, argc, "ipv6", &idx))
- afi = AFI_IP6;
- peer = peer_and_group_lookup_vty(vty, neighbor);
- if (!peer)
- return CMD_WARNING;
- if (json)
- use_json = true;
- bgp_show_peer_dampening_parameters(vty, peer, afi, safi, use_json);
- return CMD_SUCCESS;
-}
-
static int set_ecom_list(struct vty *vty, int argc, struct cmd_token **argv,
struct ecommunity **list, bool is_rt6)
{
@@ -16409,9 +16322,6 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
: "");
}
}
-
- if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_CONFIG_DAMPENING))
- bgp_config_write_peer_damp(vty, peer, afi, safi);
}
/* Address family based peer configuration display. */
@@ -16464,7 +16374,7 @@ static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi,
/* BGP flag dampening. */
if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING))
- bgp_config_write_damp(vty, bgp, afi, safi);
+ bgp_config_write_damp(vty, afi, safi);
for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group))
bgp_config_write_peer_af(vty, bgp, group->conf, afi, safi);
@@ -18247,23 +18157,6 @@ void bgp_vty_init(void)
install_element(BGP_EVPN_NODE, &neighbor_allowas_in_cmd);
install_element(BGP_EVPN_NODE, &no_neighbor_allowas_in_cmd);
- /* "neighbor dampening" commands. */
- install_element(BGP_NODE, &neighbor_damp_cmd);
- install_element(BGP_NODE, &no_neighbor_damp_cmd);
- install_element(BGP_IPV4_NODE, &neighbor_damp_cmd);
- install_element(BGP_IPV4_NODE, &no_neighbor_damp_cmd);
- install_element(BGP_IPV4M_NODE, &neighbor_damp_cmd);
- install_element(BGP_IPV4M_NODE, &no_neighbor_damp_cmd);
- install_element(BGP_IPV4L_NODE, &neighbor_damp_cmd);
- install_element(BGP_IPV4L_NODE, &no_neighbor_damp_cmd);
- install_element(BGP_IPV6_NODE, &neighbor_damp_cmd);
- install_element(BGP_IPV6_NODE, &no_neighbor_damp_cmd);
- install_element(BGP_IPV6M_NODE, &neighbor_damp_cmd);
- install_element(BGP_IPV6M_NODE, &no_neighbor_damp_cmd);
- install_element(BGP_IPV6L_NODE, &neighbor_damp_cmd);
- install_element(BGP_IPV6L_NODE, &no_neighbor_damp_cmd);
- install_element(VIEW_NODE, &show_ip_bgp_neighbor_damp_param_cmd);
-
/* address-family commands. */
install_element(BGP_NODE, &address_family_ipv4_safi_cmd);
install_element(BGP_NODE, &address_family_ipv6_safi_cmd);
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 00d91c2b27..3f8dc82a44 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -1416,8 +1416,9 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
struct aspath *aspath = info->attr->aspath;
SET_FLAG(api.message, ZAPI_MESSAGE_OPAQUE);
- api.opaque.length = strlen(aspath->str) + 1;
- memcpy(api.opaque.data, aspath->str, api.opaque.length);
+ strlcpy((char *)api.opaque.data, aspath->str,
+ sizeof(api.opaque.data));
+ api.opaque.length = strlen((char *)api.opaque.data) + 1;
}
if (allow_recursion)
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index d3f3078110..e816b98e27 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -1440,7 +1440,6 @@ void peer_xfer_config(struct peer *peer_dst, struct peer *peer_src)
/* peer flags apply */
peer_dst->flags = peer_src->flags;
- peer_dst->cap = peer_src->cap;
peer_dst->peer_gr_present_state = peer_src->peer_gr_present_state;
peer_dst->peer_gr_new_status_flag = peer_src->peer_gr_new_status_flag;
@@ -2405,14 +2404,6 @@ int peer_delete(struct peer *peer)
if (peer->bfd_config)
bgp_peer_remove_bfd_config(peer);
- /* Delete peer route flap dampening configuration. This needs to happen
- * before removing the peer from peer groups.
- */
- FOREACH_AFI_SAFI (afi, safi)
- if (peer_af_flag_check(peer, afi, safi,
- PEER_FLAG_CONFIG_DAMPENING))
- bgp_peer_damp_disable(peer, afi, safi);
-
/* If this peer belongs to peer group, clear up the
relationship. */
if (peer->group) {
@@ -3591,11 +3582,6 @@ int bgp_delete(struct bgp *bgp)
BGP_TIMER_OFF(gr_info->t_route_select);
}
- /* Delete route flap dampening configuration */
- FOREACH_AFI_SAFI (afi, safi) {
- bgp_damp_disable(bgp, afi, safi);
- }
-
if (BGP_DEBUG(zebra, ZEBRA)) {
if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
zlog_debug("Deleting Default VRF");
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 4a17b72b7f..ab487f3f4b 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -43,7 +43,6 @@
#include "bgp_labelpool.h"
#include "bgp_addpath_types.h"
#include "bgp_nexthop.h"
-#include "bgp_damp.h"
#include "bgp_io.h"
#include "lib/bfd.h"
@@ -715,9 +714,6 @@ struct bgp {
uint32_t condition_filter_count;
struct thread *t_condition_check;
- /* BGP route flap dampening configuration */
- struct bgp_damp_config damp[AFI_MAX][SAFI_MAX];
-
QOBJ_FIELDS;
};
DECLARE_QOBJ_TYPE(bgp);
@@ -1271,9 +1267,6 @@ struct peer {
/* Last update packet sent time */
time_t pkt_stime[AFI_MAX][SAFI_MAX];
- /* Peer / peer group route flap dampening configuration */
- struct bgp_damp_config damp[AFI_MAX][SAFI_MAX];
-
/* Peer Per AF flags */
/*
* Please consult the comments for *flags_override*, *flags_invert* and
@@ -1311,8 +1304,6 @@ struct peer {
#define PEER_FLAG_SEND_LARGE_COMMUNITY (1U << 26) /* Send large Communities */
#define PEER_FLAG_MAX_PREFIX_OUT (1U << 27) /* outgoing maximum prefix */
#define PEER_FLAG_MAX_PREFIX_FORCE (1U << 28) /* maximum-prefix <num> force */
-#define PEER_FLAG_CONFIG_DAMPENING (1U << 29) /* route flap dampening */
-
enum bgp_addpath_strat addpath_type[AFI_MAX][SAFI_MAX];
diff --git a/doc/developer/conf.py b/doc/developer/conf.py
index 20265f4aad..8f282c0790 100644
--- a/doc/developer/conf.py
+++ b/doc/developer/conf.py
@@ -395,8 +395,11 @@ def setup(app):
# printfrr extensions
app.add_object_type("frrfmt", "frrfmt", parse_node=parse_frrfmt)
- # css overrides for HTML theme
- app.add_stylesheet("overrides.css")
+ if "add_css_file" in dir(app):
+ app.add_css_file("overrides.css")
+ else:
+ app.add_stylesheet("overrides.css")
+
# load Pygments lexer for FRR config syntax
#
# NB: in Pygments 2.2+ this can be done with `load_lexer_from_file`, but we
diff --git a/doc/requirements.txt b/doc/requirements.txt
new file mode 100644
index 0000000000..debc7f1889
--- /dev/null
+++ b/doc/requirements.txt
@@ -0,0 +1 @@
+sphinx==4.0.2
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index f6aa5d1ca0..759fa4af73 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -499,54 +499,28 @@ Disable checking if nexthop is connected on EBGP sessions
Route Flap Dampening
--------------------
-.. clicmd:: bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]
+.. clicmd:: bgp dampening (1-45) (1-20000) (1-20000) (1-255)
- This command enables (with optionally specified dampening parameters) or
- disables route-flap dampening for all routes of a BGP instance.
-
-.. clicmd:: neighbor PEER dampening [(1-45) [(1-20000) (1-20000) (1-255)]]
-
- This command enables (with optionally specified dampening parameters) or
- disables route-flap dampening for all routes learned from a BGP peer.
-
-.. clicmd:: neighbor GROUP dampening [(1-45) [(1-20000) (1-20000) (1-255)]]
-
- This command enables (with optionally specified dampening parameters) or
- disables route-flap dampening for all routes learned from peers of a peer
- group.
+ This command enables BGP route-flap dampening and specifies dampening parameters.
half-life
- Half-life time for the penalty in minutes (default value: 15).
+ Half-life time for the penalty
reuse-threshold
- Value to start reusing a route (default value: 750).
+ Value to start reusing a route
suppress-threshold
- Value to start suppressing a route (default value: 2000).
+ Value to start suppressing a route
max-suppress
- Maximum duration to suppress a stable route in minutes (default value:
- 60).
+ Maximum duration to suppress a stable route
The route-flap damping algorithm is compatible with :rfc:`2439`. The use of
- these commands is not recommended nowadays.
+ this command is not recommended nowadays.
At the moment, route-flap dampening is not working per VRF and is working only
for IPv4 unicast and multicast.
- With different parameter sets configurable for BGP instances, peer groups and
- peers, the active dampening profile for a route is chosen on the fly,
- allowing for various changes in configuration (i.e. peer group memberships)
- during runtime. The parameter sets are taking precedence in the following
- order:
-
- 1. Peer
- 2. Peer group
- 3. BGP instance
-
- The negating commands do not allow to exclude a peer/peer group from a peer
- group/BGP instances configuration.
-
.. seealso::
https://www.ripe.net/publications/docs/ripe-378
@@ -3312,17 +3286,17 @@ structure is extended with :clicmd:`show bgp [afi] [safi]`.
It helps to identify which prefixes were installed at some point.
Here is an example of how to check what prefixes were installed starting
- with an arbitrary version::
+ with an arbitrary version:
- .. code-block:: frr
+.. code-block:: shell
- ~# vtysh -c 'show bgp ipv4 unicast json' | jq '.tableVersion'
- 9
- ~# vtysh -c 'show ip bgp version 9 json' | jq -r '.routes | keys[]'
- 192.168.3.0/24
- ~# vtysh -c 'show ip bgp version 8 json' | jq -r '.routes | keys[]'
- 192.168.2.0/24
- 192.168.3.0/24
+ # vtysh -c 'show bgp ipv4 unicast json' | jq '.tableVersion'
+ 9
+ # vtysh -c 'show ip bgp version 9 json' | jq -r '.routes | keys[]'
+ 192.168.3.0/24
+ # vtysh -c 'show ip bgp version 8 json' | jq -r '.routes | keys[]'
+ 192.168.2.0/24
+ 192.168.3.0/24
.. clicmd:: show bgp [afi] [safi] statistics
diff --git a/doc/user/conf.py b/doc/user/conf.py
index e0aec40443..6db58b07c3 100644
--- a/doc/user/conf.py
+++ b/doc/user/conf.py
@@ -386,16 +386,17 @@ def setup(app):
# node later on
app.add_object_type("clicmd", "clicmd", indextemplate="pair: %s; configuration command")
- # css overrides for HTML theme
- # Note sphinx version differences
- sver = vparse(sphinx.__version__)
-
- if sver < vparse("1.8.0"):
- app.add_stylesheet("overrides.css")
- app.add_javascript("overrides.js")
+ # I dont care how stupid this is
+ if "add_js_file" in dir(app):
+ app.add_js_file("overrides.js")
else:
+ app.add_javascript("overrides.js")
+
+ if "add_css_file" in dir(app):
app.add_css_file("overrides.css")
- app.add_js_file("overrides.js")
+ else:
+ app.add_stylesheet("overrides.css")
+
# load Pygments lexer for FRR config syntax
#
diff --git a/doc/user/ospf6d.rst b/doc/user/ospf6d.rst
index 817af33ff2..7d5f516be0 100644
--- a/doc/user/ospf6d.rst
+++ b/doc/user/ospf6d.rst
@@ -70,6 +70,19 @@ OSPF6 router
Use this command to control the maximum number of parallel routes that
OSPFv3 can support. The default is 64.
+.. clicmd:: area A.B.C.D range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]
+
+.. clicmd:: area (0-4294967295) range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]
+
+ Summarize a group of internal subnets into a single Inter-Area-Prefix LSA.
+ This command can only be used at the area boundary (ABR router).
+
+ By default, the metric of the summary route is calculated as the highest
+ metric among the summarized routes. The `cost` option, however, can be used
+ to set an explicit metric.
+
+ The `not-advertise` option, when present, prevents the summary route from
+ being advertised, effectively filtering the summarized routes.
.. _ospf6-area:
diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst
index c1d279388e..4dbbf84885 100644
--- a/doc/user/zebra.rst
+++ b/doc/user/zebra.rst
@@ -784,10 +784,11 @@ IPv6 example for OSPFv3.
.. note::
- For both IPv4 and IPv6, the IP address has to exist at the point the
- route-map is created. Be wary of race conditions if the interface is
- not created at startup. On Debian, FRR might start before ifupdown
- completes. Consider a reboot test.
+ For both IPv4 and IPv6, the IP address has to exist on some interface when
+ the route is getting installed into the system. Otherwise, kernel rejects
+ the route. To solve the problem of disappearing IPv6 addresses when the
+ interface goes down, use ``net.ipv6.conf.all.keep_addr_on_down``
+ :ref:`sysctl option <zebra-sysctl>`.
.. clicmd:: zebra route-map delay-timer (0-600)
@@ -1103,6 +1104,8 @@ For protocols requiring an IPv6 router-id, the following commands are available:
Display the user configured IPv6 router-id.
+.. _zebra-sysctl:
+
Expected sysctl settings
========================
diff --git a/nhrpd/nhrp_vty.c b/nhrpd/nhrp_vty.c
index 963fa4d995..a1c4904733 100644
--- a/nhrpd/nhrp_vty.c
+++ b/nhrpd/nhrp_vty.c
@@ -1210,7 +1210,7 @@ static int interface_config_write(struct vty *vty)
vty_out(vty, "dynamic");
else
vty_out(vty, "%pSU", &nhs->proto_addr);
- vty_out(vty, "nbma %s\n", nhs->nbma_fqdn);
+ vty_out(vty, " nbma %s\n", nhs->nbma_fqdn);
}
list_for_each_entry(mcast, &ad->mcastlist_head,
diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c
index c025dcf5bf..33cd7d8198 100644
--- a/ospf6d/ospf6_area.c
+++ b/ospf6d/ospf6_area.c
@@ -496,7 +496,7 @@ DEFUN (area_range,
struct ospf6_area *oa;
struct prefix prefix;
struct ospf6_route *range;
- uint32_t cost = OSPF_AREA_RANGE_COST_UNSPEC;
+ uint32_t cost;
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
@@ -518,16 +518,15 @@ DEFUN (area_range,
range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC;
}
+ /* default settings */
+ cost = OSPF_AREA_RANGE_COST_UNSPEC;
+ UNSET_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
+
if (argc > idx_type) {
- if (strmatch(argv[idx_type]->text, "not-advertise")) {
+ if (strmatch(argv[idx_type]->text, "not-advertise"))
SET_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
- } else if (strmatch(argv[idx_type]->text, "advertise")) {
- UNSET_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
- cost = range->path.u.cost_config;
- } else {
+ else if (strmatch(argv[idx_type]->text, "cost"))
cost = strtoul(argv[5]->arg, NULL, 10);
- UNSET_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
- }
}
range->path.u.cost_config = cost;
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index da9c0183be..7f772fdb88 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -375,10 +375,27 @@ static void ospf_passive_interface_default_update(struct ospf *ospf,
ospf_if_set_multicast(oi);
}
-static void ospf_passive_interface_update(struct interface *ifp)
+static void ospf_passive_interface_update(struct interface *ifp,
+ struct ospf_if_params *params,
+ struct in_addr addr, uint8_t newval)
{
struct route_node *rn;
+ if (OSPF_IF_PARAM_CONFIGURED(params, passive_interface)) {
+ if (params->passive_interface == newval)
+ return;
+
+ params->passive_interface = newval;
+ UNSET_IF_PARAM(params, passive_interface);
+ if (params != IF_DEF_PARAMS(ifp)) {
+ ospf_free_if_params(ifp, addr);
+ ospf_if_update_params(ifp, addr);
+ }
+ } else {
+ params->passive_interface = newval;
+ SET_IF_PARAM(params, passive_interface);
+ }
+
/*
* XXX We should call ospf_if_set_multicast on exactly those
* interfaces for which the passive property changed. It is too much
@@ -457,10 +474,7 @@ DEFUN_HIDDEN (ospf_passive_interface_addr,
params = IF_DEF_PARAMS(ifp);
}
- params->passive_interface = OSPF_IF_PASSIVE;
- SET_IF_PARAM(params, passive_interface);
-
- ospf_passive_interface_update(ifp);
+ ospf_passive_interface_update(ifp, params, addr, OSPF_IF_PASSIVE);
return CMD_SUCCESS;
}
@@ -521,14 +535,7 @@ DEFUN_HIDDEN (no_ospf_passive_interface,
params = IF_DEF_PARAMS(ifp);
}
- params->passive_interface = OSPF_IF_ACTIVE;
- UNSET_IF_PARAM(params, passive_interface);
- if (params != IF_DEF_PARAMS(ifp)) {
- ospf_free_if_params(ifp, addr);
- ospf_if_update_params(ifp, addr);
- }
-
- ospf_passive_interface_update(ifp);
+ ospf_passive_interface_update(ifp, params, addr, OSPF_IF_ACTIVE);
return CMD_SUCCESS;
}
@@ -9082,7 +9089,7 @@ DEFUN (ip_ospf_passive,
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_ipv4 = 3;
- struct in_addr addr;
+ struct in_addr addr = {.s_addr = INADDR_ANY};
struct ospf_if_params *params;
int ret;
@@ -9099,10 +9106,7 @@ DEFUN (ip_ospf_passive,
params = IF_DEF_PARAMS(ifp);
}
- params->passive_interface = OSPF_IF_PASSIVE;
- SET_IF_PARAM(params, passive_interface);
-
- ospf_passive_interface_update(ifp);
+ ospf_passive_interface_update(ifp, params, addr, OSPF_IF_PASSIVE);
return CMD_SUCCESS;
}
@@ -9118,7 +9122,7 @@ DEFUN (no_ip_ospf_passive,
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_ipv4 = 4;
- struct in_addr addr;
+ struct in_addr addr = {.s_addr = INADDR_ANY};
struct ospf_if_params *params;
int ret;
@@ -9136,14 +9140,7 @@ DEFUN (no_ip_ospf_passive,
params = IF_DEF_PARAMS(ifp);
}
- params->passive_interface = OSPF_IF_ACTIVE;
- UNSET_IF_PARAM(params, passive_interface);
- if (params != IF_DEF_PARAMS(ifp)) {
- ospf_free_if_params(ifp, addr);
- ospf_if_update_params(ifp, addr);
- }
-
- ospf_passive_interface_update(ifp);
+ ospf_passive_interface_update(ifp, params, addr, OSPF_IF_ACTIVE);
return CMD_SUCCESS;
}
@@ -11932,7 +11929,11 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
if (OSPF_IF_PARAM_CONFIGURED(params,
passive_interface)) {
- vty_out(vty, " ip ospf passive");
+ vty_out(vty, " %sip ospf passive",
+ params->passive_interface
+ == OSPF_IF_ACTIVE
+ ? "no "
+ : "");
if (params != IF_DEF_PARAMS(ifp) && rn)
vty_out(vty, " %pI4", &rn->p.u.prefix4);
vty_out(vty, "\n");
diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c
index 1bf3a619bf..3b00e779cf 100644
--- a/pimd/pim_ifchannel.c
+++ b/pimd/pim_ifchannel.c
@@ -1232,6 +1232,16 @@ int pim_ifchannel_local_membership_add(struct interface *ifp,
__FILE__, __func__, child->sg_str,
ifp->name, up->sg_str);
+ if (!child->rpf.source_nexthop.interface) {
+ /* when iif unknown, do not inherit */
+ if (PIM_DEBUG_EVENTS)
+ zlog_debug(
+ "Skipped (S,G)=%s(%s) from %s: no iif",
+ child->sg_str, ifp->name,
+ up->sg_str);
+ continue;
+ }
+
ch = pim_ifchannel_find(ifp, &child->sg);
if (pim_upstream_evaluate_join_desired_interface(
child, ch, starch)) {
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c
index a31fec036f..d706fd8693 100644
--- a/pimd/pim_rp.c
+++ b/pimd/pim_rp.c
@@ -139,11 +139,12 @@ void pim_rp_init(struct pim_instance *pim)
void pim_rp_free(struct pim_instance *pim)
{
- if (pim->rp_list)
- list_delete(&pim->rp_list);
if (pim->rp_table)
route_table_finish(pim->rp_table);
pim->rp_table = NULL;
+
+ if (pim->rp_list)
+ list_delete(&pim->rp_list);
}
/*
diff --git a/ripd/ripd.c b/ripd/ripd.c
index 7d940efd9c..3adbfeb003 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -920,9 +920,11 @@ static int rip_auth_md5(struct rip_packet *packet, struct sockaddr_in *from,
if (key == NULL || key->string == NULL)
return 0;
- strlcpy(auth_str, key->string, sizeof(auth_str));
+ memcpy(auth_str, key->string,
+ MIN(sizeof(auth_str), strlen(key->string)));
} else if (ri->auth_str)
- strlcpy(auth_str, ri->auth_str, sizeof(auth_str));
+ memcpy(auth_str, ri->auth_str,
+ MIN(sizeof(auth_str), strlen(ri->auth_str)));
if (auth_str[0] == 0)
return 0;
@@ -965,9 +967,11 @@ static void rip_auth_prepare_str_send(struct rip_interface *ri, struct key *key,
memset(auth_str, 0, len);
if (key && key->string)
- strlcpy(auth_str, key->string, len);
+ memcpy(auth_str, key->string,
+ MIN((size_t)len, strlen(key->string)));
else if (ri->auth_str)
- strlcpy(auth_str, ri->auth_str, len);
+ memcpy(auth_str, ri->auth_str,
+ MIN((size_t)len, strlen(ri->auth_str)));
return;
}
diff --git a/tests/topotests/bgp_features/exabgp.env b/tests/topotests/bgp_features/exabgp.env
deleted file mode 100644
index 6c554f5fa8..0000000000
--- a/tests/topotests/bgp_features/exabgp.env
+++ /dev/null
@@ -1,53 +0,0 @@
-
-[exabgp.api]
-encoder = text
-highres = false
-respawn = false
-socket = ''
-
-[exabgp.bgp]
-openwait = 60
-
-[exabgp.cache]
-attributes = true
-nexthops = true
-
-[exabgp.daemon]
-daemonize = true
-pid = '/var/run/exabgp/exabgp.pid'
-user = 'exabgp'
-
-[exabgp.log]
-all = false
-configuration = true
-daemon = true
-destination = '/var/log/exabgp.log'
-enable = true
-level = INFO
-message = false
-network = true
-packets = false
-parser = false
-processes = true
-reactor = true
-rib = false
-routes = false
-short = false
-timers = false
-
-[exabgp.pdb]
-enable = false
-
-[exabgp.profile]
-enable = false
-file = ''
-
-[exabgp.reactor]
-speed = 1.0
-
-[exabgp.tcp]
-acl = false
-bind = ''
-delay = 0
-once = false
-port = 179
diff --git a/tests/topotests/bgp_features/peer1/exa_readpipe.py b/tests/topotests/bgp_features/peer1/exa_readpipe.py
deleted file mode 100644
index 9e689a27e3..0000000000
--- a/tests/topotests/bgp_features/peer1/exa_readpipe.py
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env python
-"Helper script to read api commands from a pipe and feed them to ExaBGP"
-
-import sys
-
-if len(sys.argv) != 2:
- sys.exit(1)
-fifo = sys.argv[1]
-
-while True:
- pipe = open(fifo, "r")
- with pipe:
- line = pipe.readline().strip()
- if line != "":
- sys.stdout.write("{}\n".format(line))
- sys.stdout.flush()
- pipe.close()
-
-sys.exit(0)
diff --git a/tests/topotests/bgp_features/peer1/exabgp.cfg b/tests/topotests/bgp_features/peer1/exabgp.cfg
deleted file mode 100644
index 2e95252cf6..0000000000
--- a/tests/topotests/bgp_features/peer1/exabgp.cfg
+++ /dev/null
@@ -1,12 +0,0 @@
-group exabgp {
- process announce-routes {
- run "/etc/exabgp/exa_readpipe.py /var/run/exabgp_peer1.in";
- encoder text;
- }
- neighbor 192.168.101.1 {
- router-id 192.168.101.3;
- local-address 192.168.101.3;
- local-as 65403;
- peer-as 65000;
- }
-}
diff --git a/tests/topotests/bgp_features/peer2/exa_readpipe.py b/tests/topotests/bgp_features/peer2/exa_readpipe.py
deleted file mode 100644
index 9e689a27e3..0000000000
--- a/tests/topotests/bgp_features/peer2/exa_readpipe.py
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env python
-"Helper script to read api commands from a pipe and feed them to ExaBGP"
-
-import sys
-
-if len(sys.argv) != 2:
- sys.exit(1)
-fifo = sys.argv[1]
-
-while True:
- pipe = open(fifo, "r")
- with pipe:
- line = pipe.readline().strip()
- if line != "":
- sys.stdout.write("{}\n".format(line))
- sys.stdout.flush()
- pipe.close()
-
-sys.exit(0)
diff --git a/tests/topotests/bgp_features/peer2/exabgp.cfg b/tests/topotests/bgp_features/peer2/exabgp.cfg
deleted file mode 100644
index 1f65547bc5..0000000000
--- a/tests/topotests/bgp_features/peer2/exabgp.cfg
+++ /dev/null
@@ -1,12 +0,0 @@
-group exabgp {
- process announce-routes {
- run "/etc/exabgp/exa_readpipe.py /var/run/exabgp_peer2.in";
- encoder text;
- }
- neighbor 192.168.101.1 {
- router-id 192.168.101.4;
- local-address 192.168.101.4;
- local-as 65404;
- peer-as 65000;
- }
-}
diff --git a/tests/topotests/bgp_features/peer3/exa_readpipe.py b/tests/topotests/bgp_features/peer3/exa_readpipe.py
deleted file mode 100644
index 9e689a27e3..0000000000
--- a/tests/topotests/bgp_features/peer3/exa_readpipe.py
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env python
-"Helper script to read api commands from a pipe and feed them to ExaBGP"
-
-import sys
-
-if len(sys.argv) != 2:
- sys.exit(1)
-fifo = sys.argv[1]
-
-while True:
- pipe = open(fifo, "r")
- with pipe:
- line = pipe.readline().strip()
- if line != "":
- sys.stdout.write("{}\n".format(line))
- sys.stdout.flush()
- pipe.close()
-
-sys.exit(0)
diff --git a/tests/topotests/bgp_features/peer3/exabgp.cfg b/tests/topotests/bgp_features/peer3/exabgp.cfg
deleted file mode 100644
index 8632cc86c5..0000000000
--- a/tests/topotests/bgp_features/peer3/exabgp.cfg
+++ /dev/null
@@ -1,12 +0,0 @@
-group exabgp {
- process announce-routes {
- run "/etc/exabgp/exa_readpipe.py /var/run/exabgp_peer3.in";
- encoder text;
- }
- neighbor 192.168.101.1 {
- router-id 192.168.101.5;
- local-address 192.168.101.5;
- local-as 65405;
- peer-as 65000;
- }
-}
diff --git a/tests/topotests/bgp_features/peer4/exa_readpipe.py b/tests/topotests/bgp_features/peer4/exa_readpipe.py
deleted file mode 100644
index 9e689a27e3..0000000000
--- a/tests/topotests/bgp_features/peer4/exa_readpipe.py
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env python
-"Helper script to read api commands from a pipe and feed them to ExaBGP"
-
-import sys
-
-if len(sys.argv) != 2:
- sys.exit(1)
-fifo = sys.argv[1]
-
-while True:
- pipe = open(fifo, "r")
- with pipe:
- line = pipe.readline().strip()
- if line != "":
- sys.stdout.write("{}\n".format(line))
- sys.stdout.flush()
- pipe.close()
-
-sys.exit(0)
diff --git a/tests/topotests/bgp_features/peer4/exabgp.cfg b/tests/topotests/bgp_features/peer4/exabgp.cfg
deleted file mode 100644
index 06bc0d6e64..0000000000
--- a/tests/topotests/bgp_features/peer4/exabgp.cfg
+++ /dev/null
@@ -1,12 +0,0 @@
-group exabgp {
- process announce-routes {
- run "/etc/exabgp/exa_readpipe.py /var/run/exabgp_peer4.in";
- encoder text;
- }
- neighbor 192.168.101.1 {
- router-id 192.168.101.6;
- local-address 192.168.101.6;
- local-as 65406;
- peer-as 65000;
- }
-}
diff --git a/tests/topotests/bgp_features/r1/bgp_damp_announced.json b/tests/topotests/bgp_features/r1/bgp_damp_announced.json
deleted file mode 100644
index cb4a2c9b2f..0000000000
--- a/tests/topotests/bgp_features/r1/bgp_damp_announced.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "localAS":65000,
- "routes":{
- "192.168.31.0/24": [ { "valid":true, "network":"192.168.31.0\/24", "peerId":"192.168.101.3" } ],
- "192.168.32.0/24": [ { "valid":true, "network":"192.168.32.0\/24", "peerId":"192.168.101.3" } ],
- "192.168.33.0/24": [ { "valid":true, "network":"192.168.33.0\/24", "peerId":"192.168.101.3" } ],
- "192.168.34.0/24": [ { "valid":true, "network":"192.168.34.0\/24", "peerId":"192.168.101.3" } ],
- "192.168.41.0/24": [ { "valid":true, "network":"192.168.41.0\/24", "peerId":"192.168.101.4" } ],
- "192.168.42.0/24": [ { "valid":true, "network":"192.168.42.0\/24", "peerId":"192.168.101.4" } ],
- "192.168.43.0/24": [ { "valid":true, "network":"192.168.43.0\/24", "peerId":"192.168.101.4" } ],
- "192.168.44.0/24": [ { "valid":true, "network":"192.168.44.0\/24", "peerId":"192.168.101.4" } ],
- "192.168.51.0/24": [ { "valid":true, "network":"192.168.51.0\/24", "peerId":"192.168.101.5" } ],
- "192.168.52.0/24": [ { "valid":true, "network":"192.168.52.0\/24", "peerId":"192.168.101.5" } ],
- "192.168.53.0/24": [ { "valid":true, "network":"192.168.53.0\/24", "peerId":"192.168.101.5" } ],
- "192.168.54.0/24": [ { "valid":true, "network":"192.168.54.0\/24", "peerId":"192.168.101.5" } ],
- "192.168.61.0/24": [ { "valid":true, "network":"192.168.61.0\/24", "peerId":"192.168.101.6" } ],
- "192.168.62.0/24": [ { "valid":true, "network":"192.168.62.0\/24", "peerId":"192.168.101.6" } ],
- "192.168.63.0/24": [ { "valid":true, "network":"192.168.63.0\/24", "peerId":"192.168.101.6" } ],
- "192.168.64.0/24": [ { "valid":true, "network":"192.168.64.0\/24", "peerId":"192.168.101.6" } ]
- }
-}
diff --git a/tests/topotests/bgp_features/r1/bgp_damp_setup.json b/tests/topotests/bgp_features/r1/bgp_damp_setup.json
deleted file mode 100644
index f9f89db894..0000000000
--- a/tests/topotests/bgp_features/r1/bgp_damp_setup.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "ipv4Unicast":{
- "peers":{
- "192.168.101.3":{"remoteAs":65403, "state":"Established"},
- "192.168.101.4":{"remoteAs":65404, "state":"Established"},
- "192.168.101.5":{"remoteAs":65405, "state":"Established"},
- "192.168.101.6":{"remoteAs":65406, "state":"Established"}
- }
- }
-}
diff --git a/tests/topotests/bgp_features/r2/bgp_damp_announced.json b/tests/topotests/bgp_features/r2/bgp_damp_announced.json
deleted file mode 100644
index 9394358f82..0000000000
--- a/tests/topotests/bgp_features/r2/bgp_damp_announced.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "localAS":65000,
- "routes":{
- "192.168.31.0/24": [ { "network":"192.168.31.0\/24", "peerId":"192.168.0.1" } ],
- "192.168.32.0/24": [ { "network":"192.168.32.0\/24", "peerId":"192.168.0.1" } ],
- "192.168.33.0/24": [ { "network":"192.168.33.0\/24", "peerId":"192.168.0.1" } ],
- "192.168.34.0/24": [ { "network":"192.168.34.0\/24", "peerId":"192.168.0.1" } ],
- "192.168.41.0/24": [ { "network":"192.168.41.0\/24", "peerId":"192.168.0.1" } ],
- "192.168.42.0/24": [ { "network":"192.168.42.0\/24", "peerId":"192.168.0.1" } ],
- "192.168.43.0/24": [ { "network":"192.168.43.0\/24", "peerId":"192.168.0.1" } ],
- "192.168.44.0/24": [ { "network":"192.168.44.0\/24", "peerId":"192.168.0.1" } ],
- "192.168.51.0/24": [ { "network":"192.168.51.0\/24", "peerId":"192.168.0.1" } ],
- "192.168.52.0/24": [ { "network":"192.168.52.0\/24", "peerId":"192.168.0.1" } ],
- "192.168.53.0/24": [ { "network":"192.168.53.0\/24", "peerId":"192.168.0.1" } ],
- "192.168.54.0/24": [ { "network":"192.168.54.0\/24", "peerId":"192.168.0.1" } ],
- "192.168.61.0/24": [ { "network":"192.168.61.0\/24", "peerId":"192.168.0.1" } ],
- "192.168.62.0/24": [ { "network":"192.168.62.0\/24", "peerId":"192.168.0.1" } ],
- "192.168.63.0/24": [ { "network":"192.168.63.0\/24", "peerId":"192.168.0.1" } ],
- "192.168.64.0/24": [ { "network":"192.168.64.0\/24", "peerId":"192.168.0.1" } ]
- }
-}
diff --git a/tests/topotests/bgp_features/r2/bgp_damp_withdrawn.json b/tests/topotests/bgp_features/r2/bgp_damp_withdrawn.json
deleted file mode 100644
index f3c54a70a1..0000000000
--- a/tests/topotests/bgp_features/r2/bgp_damp_withdrawn.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "192.168.31.0/24": null,
- "192.168.32.0/24": null,
- "192.168.33.0/24": null,
- "192.168.34.0/24": null,
- "192.168.41.0/24": null,
- "192.168.42.0/24": null,
- "192.168.43.0/24": null,
- "192.168.44.0/24": null,
- "192.168.51.0/24": null,
- "192.168.52.0/24": null,
- "192.168.53.0/24": null,
- "192.168.54.0/24": null,
- "192.168.61.0/24": null,
- "192.168.62.0/24": null,
- "192.168.63.0/24": null,
- "192.168.64.0/24": null
-}
diff --git a/tests/topotests/bgp_features/test_bgp_features.py b/tests/topotests/bgp_features/test_bgp_features.py
index a68508c4ae..d19b7722d0 100644
--- a/tests/topotests/bgp_features/test_bgp_features.py
+++ b/tests/topotests/bgp_features/test_bgp_features.py
@@ -33,7 +33,6 @@ import sys
import pytest
import re
import time
-from time import sleep
# Save the Current Working Directory to find configuration files.
CWD = os.path.dirname(os.path.realpath(__file__))
@@ -67,14 +66,6 @@ class BGPFeaturesTopo1(Topo):
for rtrNum in range(1, 6):
tgen.add_router("r{}".format(rtrNum))
- # create ExaBGP peers
- for peer_num in range(1, 5):
- tgen.add_exabgp_peer(
- "peer{}".format(peer_num),
- ip="192.168.101.{}".format(peer_num + 2),
- defaultRoute="via 192.168.101.1",
- )
-
# Setup Switches and connections
for swNum in range(1, 11):
tgen.add_switch("sw{}".format(swNum))
@@ -100,12 +91,6 @@ class BGPFeaturesTopo1(Topo):
tgen.gears["r2"].add_link(tgen.gears["sw5"])
tgen.gears["r5"].add_link(tgen.gears["sw5"])
- # Add ExaBGP peers to sw4
- tgen.gears["peer1"].add_link(tgen.gears["sw4"])
- tgen.gears["peer2"].add_link(tgen.gears["sw4"])
- tgen.gears["peer3"].add_link(tgen.gears["sw4"])
- tgen.gears["peer4"].add_link(tgen.gears["sw4"])
-
#####################################################
#
@@ -1110,662 +1095,6 @@ def test_bgp_delayopen_dual():
# end test_bgp_delayopen_dual
-def test_bgp_dampening_setup():
- "BGP route-flap dampening test setup"
-
- # This test starts four ExaBGP peers, adds them as neighbors to the
- # configuration of router r1 and checks if connections get established.
-
- tgen = get_topogen()
-
- # Skip if previous fatal error condition is raised
- if tgen.routers_have_failure():
- pytest.skip(tgen.errors)
-
- logger.info("Starting BGP route-flap dampening test setup")
-
- # Start ExaBGP peers connected to r1 via switch 4
- logger.info("Starting ExaBGP peers")
- for peer_num in range(1, 5):
- logger.info("Creating named pipe for ExaBGP peer peer{}".format(peer_num))
- fifo_in = "/var/run/exabgp_peer{}.in".format(peer_num)
- if os.path.exists(fifo_in):
- os.remove(fifo_in)
- os.mkfifo(fifo_in, 0o777)
- logger.info("Starting ExaBGP on peer peer{}".format(peer_num))
- peer = tgen.gears["peer{}".format(peer_num)]
- peer_dir = os.path.join(CWD, "peer{}".format(peer_num))
- env_file = os.path.join(CWD, "exabgp.env")
- peer.start(peer_dir, env_file)
-
- # Add ExaBGP peers to configuration of router r2
- logger.info("Adding ExaBGP peers as neighbors to configuration of router r2")
- tgen.net["r1"].cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "neighbor 192.168.101.3 remote-as 65403"'
- )
- tgen.net["r1"].cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "neighbor 192.168.101.3 route-map testmap-in"'
- )
- tgen.net["r1"].cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "neighbor 192.168.101.3 route-map testmap-out"'
- )
- tgen.net["r1"].cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "neighbor 192.168.101.4 remote-as 65404"'
- )
- tgen.net["r1"].cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "neighbor 192.168.101.4 route-map testmap-in"'
- )
- tgen.net["r1"].cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "neighbor 192.168.101.4 route-map testmap-out"'
- )
- tgen.net["r1"].cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "neighbor 192.168.101.5 remote-as 65405"'
- )
- tgen.net["r1"].cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "neighbor 192.168.101.5 route-map testmap-in"'
- )
- tgen.net["r1"].cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "neighbor 192.168.101.5 route-map testmap-out"'
- )
- tgen.net["r1"].cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "neighbor 192.168.101.6 remote-as 65406"'
- )
- tgen.net["r1"].cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "neighbor 192.168.101.6 route-map testmap-in"'
- )
- tgen.net["r1"].cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "neighbor 192.168.101.6 route-map testmap-out"'
- )
-
- # Check if exabgp peers are up and running
- logger.info("Checking for established connections to ExaBGP peers on router r1")
- router = tgen.gears["r1"]
- reffile = os.path.join(CWD, "r1/bgp_damp_setup.json")
- expected = json.loads(open(reffile).read())
- test_func = functools.partial(
- topotest.router_json_cmp, router, "show ip bgp summary json", expected
- )
- _, res = topotest.run_and_expect(test_func, None, count=10, wait=1)
- assertmsg = (
- "BGP session on r1 did not establish connections with one ore more ExaBGP peers"
- )
- assert res is None, assertmsg
-
- # end test_bgp_dampening_setup
-
-
-def test_bgp_dampening_route_announce():
- "Test of BGP route-flap dampening route announcement"
-
- # This test checks if the four ExaBGP peers can announce routes to router
- # r1 and if these routes get forwarded to router r2.
-
- tgen = get_topogen()
-
- # Skip if previous fatal error condition is raised
- if tgen.routers_have_failure():
- pytest.skip(tgen.errors)
-
- logger.info("Starting test of BGP route-flap dampening route announcement")
-
- # Announce routes on exabgp peers to r2
- logger.info("Announcing routes on ExaBGP peers to r1")
- for prefix_iter in range(1, 5):
- for peer_num in range(1, 5):
- pipe = open("/run/exabgp_peer{}.in".format(peer_num), "w")
- with pipe:
- pipe.write(
- "announce route 192.168.{}{}.0/24 next-hop 192.168.101.{}\n".format(
- (peer_num + 2), prefix_iter, (peer_num + 2)
- )
- )
- pipe.close()
- sleep(0.1) # ExaBGP API command processing delay
-
- # Check if routes announced by ExaBGP peers are present in RIB of router r1
- logger.info(
- "Checking if routes announced by ExaBGP peers are present in RIB of router r1"
- )
- router = tgen.gears["r1"]
- reffile = os.path.join(CWD, "r1/bgp_damp_announced.json")
- expected = json.loads(open(reffile).read())
- test_func = functools.partial(
- topotest.router_json_cmp, router, "show ip bgp json", expected
- )
- _, res = topotest.run_and_expect(test_func, None, count=10, wait=1)
- assertmsg = (
- "BGP session on router r1 did not receive routes announced by ExaBGP peers"
- )
- assert res is None, assertmsg
-
- # Check if routes announced by ExaBGP peers to router r1 have been forwarded
- # and are now present in RIB of router r2
- logger.info(
- "Checking if forwarded routes announced by ExaBGP peers are present in RIB of router r2"
- )
- router = tgen.gears["r2"]
- reffile = os.path.join(CWD, "r2/bgp_damp_announced.json")
- expected = json.loads(open(reffile).read())
- test_func = functools.partial(
- topotest.router_json_cmp, router, "show ip bgp json", expected
- )
- _, res = topotest.run_and_expect(test_func, None, count=10, wait=1)
- assertmsg = "BGP session on router r2 did not receive routes announced by ExaBGP peers forwarded by router r1"
- assert res is None, assertmsg
-
- # end test_bgp_dampening_route_announce
-
-
-def test_bgp_dampening_disabled():
- "Test of BGP route-flapping with dampening disabled"
-
- # This test verifies that flapped routes do not get withdrawn from the RIB
- # of router r1 if dampening is disabled.
-
- tgen = get_topogen()
-
- # Skip if previous fatal error condition is raised
- if tgen.routers_have_failure():
- pytest.skip(tgen.errors)
-
- logger.info("Starting test of BGP route-flapping with dampening disabled")
-
- # Flapping routes on ExaBGP peer peer1
- logger.info(
- "Flapping routes on ExaBGP peer peer1 with route-flap dampening disabled"
- )
- for _ in range(1, 5):
- for prefix_iter in range(1, 5):
- pipe = open("/run/exabgp_peer1.in", "w")
- with pipe:
- pipe.write(
- "withdraw route 192.168.3{}.0/24 next-hop 192.168.101.3\n".format(
- prefix_iter
- )
- )
- pipe.close()
- sleep(0.1) # ExaBGP API command processing delay
- sleep(1) # Give the BGP session on router r1 time to process routes
- for prefix_iter in range(1, 5):
- pipe = open("/run/exabgp_peer1.in", "w")
- with pipe:
- pipe.write(
- "announce route 192.168.3{}.0/24 next-hop 192.168.101.3\n".format(
- prefix_iter
- )
- )
- pipe.close()
- sleep(0.1) # ExaBGP API command processing delay
-
- # Verify flapped routes are still present in RIB of router r1
- logger.info(
- "Verifying that the flapped routes are still present in RIB of router r1"
- )
- router = tgen.gears["r1"]
- reffile = os.path.join(CWD, "r1/bgp_damp_announced.json")
- expected = json.loads(open(reffile).read())
- test_func = functools.partial(
- topotest.router_json_cmp, router, "show ip bgp json", expected
- )
- _, res = topotest.run_and_expect(test_func, None, count=10, wait=1)
- assertmsg = "BGP session on router r1 removed flapped routes despite route-flap dampening being disabled"
- assert res is None, assertmsg
-
- # end test_bgp_dampening_disabled
-
-
-def test_bgp_dampening_config():
- "Test of BGP route-flap dampening configuration"
-
- # This test adds peer-group group1 with peers peer1 and peer2 to the
- # configuration of router r1, sets up dampening configurations with
- # different profiles and verifies the configured dampening parameters.
-
- tgen = get_topogen()
- r_1 = tgen.net["r1"]
-
- # Skip if previous fatal error condition is raised
- if tgen.routers_have_failure():
- pytest.skip(tgen.errors)
-
- logger.info("Starting test of BGP route-flap dampening configuration")
-
- # Add peer-group group1 with peers peer1 and peer2
- logger.info(
- "Creating peer-group group1 and adding ExaBGP peers peer1 and peer2 to it"
- )
- r_1.cmd('vtysh -c "conf t" -c "router bgp 65000" -c "neighbor group1 peer-group"')
- r_1.cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "neighbor 192.168.101.3 peer-group group1"'
- ) # peer1
- r_1.cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "neighbor 192.168.101.4 peer-group group1"'
- ) # peer2
-
- # Enable different dampening profiles for peer1, peer3, group1 and global
- # configuration
- logger.info(
- "Enabling different dampening profiles for peer1, peer3, group1 and global configuration"
- )
- r_1.cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "bgp dampening 30 300 900 90"'
- )
- r_1.cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "neighbor group1 dampening 20 200 600 60"'
- )
- r_1.cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "neighbor 192.168.101.3 dampening 10 100 300 30"'
- ) # peer1
- r_1.cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "neighbor 192.168.101.5 dampening 10 100 300 30"'
- ) # peer3
-
- # Verify route-flap dampening configuration
- logger.info("Verifying route-flap dampening configuration on router r1")
- vtyout = r_1.cmd('vtysh -c "show running-config"')
- assertmsg = "BGP Session on r1 does not show enabled global route-flap dampening in running configuration"
- assert re.search("bgp dampening 30 300 900 90", vtyout), assertmsg
- assertmsg = "BGP Session on r1 does not show route-flap dampening enabled for peer-group group1 in running configuration"
- assert re.search("neighbor group1 dampening 20 200 600 60", vtyout), assertmsg
- assertmsg = "BGP Session on r1 does not show route-flap dampening enabled for peer peer1 in running configuration"
- assert re.search(
- "neighbor 192.168.101.3 dampening 10 100 300 30", vtyout
- ), assertmsg
- assertmsg = "BGP Session on r1 does not show route-flap dampening enabled for peer peer3 in running configuration"
- assert re.search(
- "neighbor 192.168.101.5 dampening 10 100 300 30", vtyout
- ), assertmsg
-
- # end test_bgp_dampening_config
-
-
-def test_bgp_dampening_profile_peer_over_group():
- "Test of BGP route-flap dampening profile preferences: peer over group"
-
- # This test verifies that the dampening profile of a peer takes precedence
- # over the dampening profile of its peer-group by flapping the peers routes
- # until dampened and comparing the reuse times to the one specified in the
- # dampening configuration.
-
- tgen = get_topogen()
- r_1 = tgen.net["r1"]
-
- # Skip if previous fatal error condition is raised
- if tgen.routers_have_failure():
- pytest.skip(tgen.errors)
-
- logger.info(
- "Starting test of BGP route-flap dampening profile preferences: peer over group"
- )
-
- # Flapping routes on ExaBGP peer peer1
- logger.info(
- "Flapping routes on ExaBGP peer peer1 with route-flap dampening enabled"
- )
- for _ in range(1, 5):
- for prefix_iter in range(1, 5):
- pipe = open("/run/exabgp_peer1.in", "w")
- with pipe:
- pipe.write(
- "withdraw route 192.168.3{}.0/24 next-hop 192.168.101.3\n".format(
- prefix_iter
- )
- )
- pipe.close()
- sleep(0.1) # ExaBGP API command processing delay
- sleep(1) # Give the BGP session on router r1 time to process routes
- for prefix_iter in range(1, 5):
- pipe = open("/run/exabgp_peer1.in", "w")
- with pipe:
- pipe.write(
- "announce route 192.168.3{}.0/24 next-hop 192.168.101.3\n".format(
- prefix_iter
- )
- )
- pipe.close()
- sleep(0.1) # ExaBGP API command processing delay
-
- # Check damped paths on r1 for routes of peer1 witn peer profile
- logger.info(
- "Checking if router r1 used the correct dampening profile on routes flapped by ExaBGP peer peer1"
- )
- sleep(5) # Wait 5 seconds for paths to show up in dampened-paths list
- vtyout = r_1.cmd('vtysh -c "show ip bgp dampening dampened-paths"')
- routes = re.findall(r"\*d 192\.168\.3\d\.0\/24.*", vtyout)
- assertmsg = (
- "BGP session on router r1 did not dampen routes flapped by ExaBGP peer peer1"
- )
- assert len(routes) == 4, assertmsg
- assertmsg = "BGP session on router r1 used wrong dampening profile for a route flapped by ExaBGP peer peer1"
- for route in routes:
- assert (int(route.split()[3].split(":")[0]) == 0) and ( # hours of reuse time
- 35 > int(route.split()[3].split(":")[1]) > 25
- ), assertmsg # minutes of reuse time
-
- # end test_bgp_dampening_profile_peer_over_group
-
-
-def test_bgp_dampening_profile_group_over_global():
- "Test of BGP route-flap dampening profile preferences: group over global"
-
- # This test verifies that the dampening profile of a peer-group takes
- # precedence over the global dampening profile by flapping the routes of a
- # peer-group member until dampened and comparing the reuse times to the one
- # specified in the dampening configuration.
-
- tgen = get_topogen()
- r_1 = tgen.net["r1"]
-
- # Skip if previous fatal error condition is raised
- if tgen.routers_have_failure():
- pytest.skip(tgen.errors)
-
- logger.info(
- "Starting test of BGP route-flap dampening profile preferences: group over global"
- )
-
- # Flapping routes on ExaBGP peer peer2
- logger.info(
- "Flapping routes on ExaBGP peer peer2 with route-flap dampening enabled"
- )
- for _ in range(1, 5):
- for prefix_iter in range(1, 5):
- pipe = open("/run/exabgp_peer2.in", "w")
- with pipe:
- pipe.write(
- "withdraw route 192.168.4{}.0/24 next-hop 192.168.101.4\n".format(
- prefix_iter
- )
- )
- pipe.close()
- sleep(0.1) # ExaBGP API command processing delay
- sleep(1) # Give the BGP session on router r1 time to process routes
- for prefix_iter in range(1, 5):
- pipe = open("/run/exabgp_peer2.in", "w")
- with pipe:
- pipe.write(
- "announce route 192.168.4{}.0/24 next-hop 192.168.101.4\n".format(
- prefix_iter
- )
- )
- pipe.close()
- sleep(0.1) # ExaBGP API command processing delay
-
- # Check damped paths on r1 for routes of peer2 witn group profile
- logger.info(
- "Checking if router r1 used the correct dampening profile on routes flapped by ExaBGP peer peer2"
- )
- sleep(5) # wait 5 seconds for paths to shop up in damp list
- vtyout = r_1.cmd('vtysh -c "show ip bgp dampening dampened-paths"')
- routes = re.findall(r"\*d 192\.168\.4\d\.0\/24.*", vtyout)
- assertmsg = (
- "BGP session on router r1 did not dampen routes flapped by ExaBGP peer peer2"
- )
- assert len(routes) == 4, assertmsg
- assertmsg = "BGP session on router r1 used wrong dampening profile for a route flapped by ExaBGP peer peer2"
- for route in routes:
- assert (int(route.split()[3].split(":")[0]) == 0) and ( # hours of reuse time
- 65 > int(route.split()[3].split(":")[1]) > 55
- ), assertmsg # minutes of reuse time
-
- # end test_bgp_dampening_profile_group_over_global
-
-
-def test_bgp_dampening_profile_peer_over_global():
- "Test of BGP route-flap dampening profile preferences: peer over global"
-
- # This test verifies that the dampening profile of a peer takes precedence
- # over the global dampening profile by flapping the routes of the peer until
- # dampened and comparing the reuse times to the one specified in the
- # dampening configuration.
-
- tgen = get_topogen()
- r_1 = tgen.net["r1"]
-
- # Skip if previous fatal error condition is raised
- if tgen.routers_have_failure():
- pytest.skip(tgen.errors)
-
- logger.info(
- "Starting test of BGP route-flap dampening profile preferences: peer over global"
- )
-
- # Flapping routes on ExaBGP peer peer3
- logger.info(
- "Flapping routes on ExaBGP peer peer3 with route-flap dampening enabled"
- )
- for _ in range(1, 5):
- for prefix_iter in range(1, 5):
- pipe = open("/run/exabgp_peer3.in", "w")
- with pipe:
- pipe.write(
- "withdraw route 192.168.5{}.0/24 next-hop 192.168.101.5\n".format(
- prefix_iter
- )
- )
- pipe.close()
- sleep(0.1) # ExaBGP API command processing delay
- sleep(1) # Give the BGP session on router r1 time to process routes
- for prefix_iter in range(1, 5):
- pipe = open("/run/exabgp_peer3.in", "w")
- with pipe:
- pipe.write(
- "announce route 192.168.5{}.0/24 next-hop 192.168.101.5\n".format(
- prefix_iter
- )
- )
- pipe.close()
- sleep(0.1) # ExaBGP API command processing delay
-
- # Check damped paths on r1 for routes of peer3 witn peer profile
- logger.info(
- "Checking if router r1 used the correct dampening profile on routes flapped by ExaBGP peer peer3"
- )
- sleep(5) # wait 5 seconds for paths to shop up in damp list
- vtyout = r_1.cmd('vtysh -c "show ip bgp dampening dampened-paths"')
- routes = re.findall(r"\*d 192\.168\.5\d\.0\/24.*", vtyout)
- assertmsg = (
- "BGP session on router r1 did not dampen routes flapped by ExaBGP peer peer3"
- )
- assert len(routes) == 4, assertmsg
- assertmsg = "BGP session on router r1 used wrong dampening profile for a route flapped by ExaBGP peer peer3"
- for route in routes:
- assert (int(route.split()[3].split(":")[0]) == 0) and ( # hours of reuse time
- 35 > int(route.split()[3].split(":")[1]) > 25
- ), assertmsg # minutes of reuse time
-
- # end test_bgp_dampening_profile_peer_over_global
-
-
-def test_bgp_dampening_profile_global():
- "Test of BGP route-flap dampening global profile"
-
- # This test verifies the application of the global dampening profile by
- # flapping the routes of a peer until dampened and comparing the reuse times
- # to the one specified in the dampening configuration.
-
- tgen = get_topogen()
- r_1 = tgen.net["r1"]
-
- # Skip if previous fatal error condition is raised
- if tgen.routers_have_failure():
- pytest.skip(tgen.errors)
-
- logger.info("Starting test of BGP route-flap dampening global profile")
-
- # Flapping routes on ExaBGP peer peer4
- logger.info(
- "Flapping routes on ExaBGP peer peer4 with route-flap dampening enabled"
- )
- for _ in range(1, 5):
- for prefix_iter in range(1, 5):
- pipe = open("/run/exabgp_peer4.in", "w")
- with pipe:
- pipe.write(
- "withdraw route 192.168.6{}.0/24 next-hop 192.168.101.6\n".format(
- prefix_iter
- )
- )
- pipe.close()
- sleep(0.1) # ExaBGP API command processing delay
- sleep(1) # Give the BGP session on router r1 time to process routes
- for prefix_iter in range(1, 5):
- pipe = open("/run/exabgp_peer4.in", "w")
- with pipe:
- pipe.write(
- "announce route 192.168.6{}.0/24 next-hop 192.168.101.6\n".format(
- prefix_iter
- )
- )
- pipe.close()
- sleep(0.1) # ExaBGP API command processing delay
-
- # Check damped paths on r1 for routes of peer4 witn global profile
- logger.info(
- "Checking if router r1 used the global dampening profile on routes flapped by ExaBGP peer peer4"
- )
- sleep(5) # wait 5 seconds for paths to shop up in damp list
- vtyout = r_1.cmd('vtysh -c "show ip bgp dampening dampened-paths"')
- routes = re.findall(r"\*d 192\.168\.6\d\.0\/24.*", vtyout)
- assertmsg = (
- "BGP session on router r1 did not dampen routes flapped by ExaBGP peer peer4"
- )
- assert len(routes) == 4, assertmsg
- assertmsg = "BGP session on router r1 did not use the global dampening profile for a route flapped by ExaBGP peer peer4"
- for route in routes:
- assert (int(route.split()[3].split(":")[0]) == 1) and ( # hours of reuse time
- 35 > int(route.split()[3].split(":")[1]) > 25
- ), assertmsg # minutes of reuse time
-
- # end test_bgp_dampening_profile_global
-
-
-def test_bgp_dampening_withdaw():
- "Test BGP route-flap dampening route withdraw"
-
- # This test verifies that the withrawl of dampened routes from the RIB of
- # router r1 was propagated to router r2.
-
- tgen = get_topogen()
-
- # Skip if previous fatal error condition is raised
- if tgen.routers_have_failure():
- pytest.skip(tgen.errors)
-
- logger.info("Starting test of BGP route-flap dampening route withdraw")
-
- # Check if routes dampened on router r1 have been withdrawn from the RIB on
- # router r2
- logger.info(
- "Checking if routes dampened on router r1 have been withdrawn of RIB on router r2"
- )
- reffile = os.path.join(CWD, "r2/bgp_damp_withdrawn.json")
- expected = json.loads(open(reffile).read())
- test_func = functools.partial(
- topotest.router_json_cmp, tgen.gears["r2"], "show ip bgp json", expected
- )
- _, res = topotest.run_and_expect(test_func, None, count=5, wait=1)
- assertmsg = "BGP session on router r2 did not receive withdraw of routes dampened on router r1"
- assert res is None, assertmsg
-
- # end test_bgp_dampening_withdaw
-
-
-def test_bgp_dampening_cleanup():
- "BGP route-flap dampening test cleanup"
-
- # This test cleans up after other tests associated with route-flap dampening
- # by disabling all dampening configurations, removing added peers and
- # peer-groups from the configuration on router r1, and shutting down ExaBGP
- # peers peer1, peer2 and peer3.
-
- tgen = get_topogen()
- r_1 = tgen.net["r1"]
-
- # Skip if previous fatal error condition is raised
- if tgen.routers_have_failure():
- pytest.skip(tgen.errors)
-
- logger.info("Starting BGP route-flap dampening test cleanup")
-
- # Disable all dampening configurations
- logger.info("Disabling all dampening configurations")
- r_1.cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "no bgp dampening"'
- )
- r_1.cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "no neighbor group1 dampening"'
- )
- r_1.cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "no neighbor 192.168.101.3 dampening"'
- )
- r_1.cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "no neighbor 192.168.101.5 dampening"'
- )
-
- # Remove ExaBGP peers from configuration of router r1
- logger.info("Removing ExaBGP peers from configuration of router r1")
- for router_num in range(3, 7):
- r_1.cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "no neighbor 192.168.101.{}"'.format(
- router_num
- )
- )
-
- # Remove peer-group group1 from configuration of router r1
- logger.info("Removing peer-group group1 peers from configuration of router r1")
- r_1.cmd(
- 'vtysh -c "conf t" -c "router bgp 65000" -c "no neighbor group1 peer-group"'
- )
-
- # Stop ExaBGP peers and remove associated named pipes
- logger.info("Stopping ExaBGP peers and removing associated named pipes")
- for peer_num in range(1, 5):
- logger.info("Terminating ExaBGP on peer peer{}".format(peer_num))
- peer = tgen.gears["peer{}".format(peer_num)]
- logger.info("Removing named pipe of ExaBGP peer peer{}".format(peer_num))
- fifo_in = "/var/run/exabgp_peer{}.in".format(peer_num)
- peer.stop()
- if os.path.exists(fifo_in):
- os.remove(fifo_in)
-
- # end test_bgp_dampening_cleanup
-
-
-def test_bgp_dampening_aftermath():
- "BGP route-flap dampening aftermath test"
-
- # This test verifies routers r1 and r2 not being affected by the route-flap
- # dampening test series.
-
- tgen = get_topogen()
-
- # Skip if previous fatal error condition is raised
- if tgen.routers_have_failure():
- pytest.skip(tgen.errors)
-
- # Check BGP Summary on routers r1 and r2
- for rtr_num in [1, 2]:
- logger.info(
- "Checking if BGP router on r{} remains unaffected by route-flap dampening tests".format(
- rtr_num
- )
- )
- router = tgen.gears["r{}".format(rtr_num)]
- reffile = os.path.join(CWD, "r{}/show_bgp.json".format(rtr_num))
- expected = json.loads(open(reffile).read())
- test_func = functools.partial(
- topotest.router_json_cmp, router, "show ip bgp json", expected
- )
- _, res = topotest.run_and_expect(test_func, None, count=10, wait=2)
- assertmsg = "BGP routes on router r{} are wrong after route-flap dampening tests".format(
- rtr_num
- )
- assert res is None, assertmsg
-
- # end test_bgp_dampening_aftermath
-
-
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
sys.exit(pytest.main(args))
diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c
index 07a8288605..855e19dc45 100644
--- a/zebra/zebra_fpm.c
+++ b/zebra/zebra_fpm.c
@@ -1002,7 +1002,6 @@ static int zfpm_build_route_updates(void)
data_len = zfpm_encode_route(dest, re, (char *)data,
buf_end - data, &msg_type);
- assert(data_len);
if (data_len) {
hdr->msg_type = msg_type;
msg_len = fpm_data_len_to_msg_len(data_len);
@@ -1013,6 +1012,9 @@ static int zfpm_build_route_updates(void)
zfpm_g->stats.route_adds++;
else
zfpm_g->stats.route_dels++;
+ } else {
+ zlog_err("%s: Encoding Prefix: %pRN No valid nexthops",
+ __func__, dest->rnode);
}
}
diff --git a/zebra/zebra_routemap_nb_config.c b/zebra/zebra_routemap_nb_config.c
index 8f5660610f..5bcfb720e1 100644
--- a/zebra/zebra_routemap_nb_config.c
+++ b/zebra/zebra_routemap_nb_config.c
@@ -247,9 +247,7 @@ lib_route_map_entry_set_action_rmap_set_action_ipv4_src_address_modify(
struct nb_cb_modify_args *args)
{
struct routemap_hook_context *rhc;
- struct interface *pif = NULL;
const char *source;
- struct vrf *vrf;
struct prefix p;
int rv;
@@ -262,18 +260,6 @@ lib_route_map_entry_set_action_rmap_set_action_ipv4_src_address_modify(
yang_dnode_get_string(args->dnode, NULL));
return NB_ERR_VALIDATION;
}
-
- RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) {
- pif = if_lookup_exact_address(&p.u.prefix4, AF_INET,
- vrf->vrf_id);
- if (pif != NULL)
- break;
- }
- if (pif == NULL) {
- zlog_warn("%s: is not a local address: %s", __func__,
- yang_dnode_get_string(args->dnode, NULL));
- return NB_ERR_VALIDATION;
- }
return NB_OK;
case NB_EV_PREPARE:
case NB_EV_ABORT:
@@ -325,9 +311,7 @@ lib_route_map_entry_set_action_rmap_set_action_ipv6_src_address_modify(
struct nb_cb_modify_args *args)
{
struct routemap_hook_context *rhc;
- struct interface *pif = NULL;
const char *source;
- struct vrf *vrf;
struct prefix p;
int rv;
@@ -340,18 +324,6 @@ lib_route_map_entry_set_action_rmap_set_action_ipv6_src_address_modify(
yang_dnode_get_string(args->dnode, NULL));
return NB_ERR_VALIDATION;
}
-
- RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) {
- pif = if_lookup_exact_address(&p.u.prefix6, AF_INET6,
- vrf->vrf_id);
- if (pif != NULL)
- break;
- }
- if (pif == NULL) {
- zlog_warn("%s: is not a local address: %s", __func__,
- yang_dnode_get_string(args->dnode, NULL));
- return NB_ERR_VALIDATION;
- }
return NB_OK;
case NB_EV_PREPARE:
case NB_EV_ABORT: