summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bfdd/bfdd_nb_config.c1
-rw-r--r--lib/routemap.c9
-rw-r--r--m4/ax_python.m43
-rw-r--r--ospfd/ospf_dump.c40
-rw-r--r--ospfd/ospf_dump.h4
-rw-r--r--ospfd/ospf_lsa.c25
-rw-r--r--ospfd/ospf_zebra.c249
-rw-r--r--ospfd/ospf_zebra.h7
-rw-r--r--ospfd/ospfd.c1
-rw-r--r--ospfd/ospfd.h2
-rwxr-xr-xtests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py12
-rwxr-xr-xtests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py12
-rw-r--r--tests/topotests/lib/bgp.py21
-rw-r--r--tests/topotests/lib/common_config.py6
14 files changed, 355 insertions, 37 deletions
diff --git a/bfdd/bfdd_nb_config.c b/bfdd/bfdd_nb_config.c
index de11997d1..915a2f641 100644
--- a/bfdd/bfdd_nb_config.c
+++ b/bfdd/bfdd_nb_config.c
@@ -257,6 +257,7 @@ int bfdd_bfd_profile_detection_multiplier_modify(struct nb_cb_modify_args *args)
bp = nb_running_get_entry(args->dnode, NULL, true);
bp->detection_multiplier = yang_dnode_get_uint8(args->dnode, NULL);
+ bfd_profile_update(bp);
return NB_OK;
}
diff --git a/lib/routemap.c b/lib/routemap.c
index 7749ea4cc..1415a9e2e 100644
--- a/lib/routemap.c
+++ b/lib/routemap.c
@@ -1692,14 +1692,19 @@ route_map_get_index(struct route_map *map, const struct prefix *prefix,
* more noops, we retain this return value and
* return this eventually if there are no
* matches.
+ * If a best match route-map index already
+ * exists, do not reset the match_ret.
*/
- if (*match_ret != RMAP_NOMATCH)
+ if (!best_index && (*match_ret != RMAP_NOMATCH))
*match_ret = ret;
} else {
/*
* ret is RMAP_NOMATCH.
+ * If a best match route-map index already
+ * exists, do not reset the match_ret.
*/
- *match_ret = ret;
+ if (!best_index)
+ *match_ret = ret;
}
}
diff --git a/m4/ax_python.m4 b/m4/ax_python.m4
index 9f43ea0ab..91d12b99b 100644
--- a/m4/ax_python.m4
+++ b/m4/ax_python.m4
@@ -186,7 +186,8 @@ AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_MSG_RESULT([yes])
PYTHON_CFLAGS="`\"$pycfg\" --includes`"
- if test x"${py_ver}" = x"3.8" || test x"{py_ver}" = x"3.9"; then
+ minor_ver=${py_ver#*\.}
+ if test $((minor_ver)) -gt 7; then
PYTHON_LIBS="`\"$pycfg\" --ldflags --embed`"
else
PYTHON_LIBS="`\"$pycfg\" --ldflags`"
diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c
index 3dcb2b481..dcc479def 100644
--- a/ospfd/ospf_dump.c
+++ b/ospfd/ospf_dump.c
@@ -53,10 +53,11 @@ unsigned long conf_debug_ospf_nssa = 0;
unsigned long conf_debug_ospf_te = 0;
unsigned long conf_debug_ospf_ext = 0;
unsigned long conf_debug_ospf_sr = 0;
+unsigned long conf_debug_ospf_defaultinfo = 0;
/* Enable debug option variables -- valid only session. */
unsigned long term_debug_ospf_packet[5] = {0, 0, 0, 0, 0};
-unsigned long term_debug_ospf_event = 0;
+unsigned long term_debug_ospf_event;
unsigned long term_debug_ospf_ism = 0;
unsigned long term_debug_ospf_nsm = 0;
unsigned long term_debug_ospf_lsa = 0;
@@ -65,6 +66,7 @@ unsigned long term_debug_ospf_nssa = 0;
unsigned long term_debug_ospf_te = 0;
unsigned long term_debug_ospf_ext = 0;
unsigned long term_debug_ospf_sr = 0;
+unsigned long term_debug_ospf_defaultinfo;
const char *ospf_redist_string(unsigned int route_type)
{
@@ -1447,6 +1449,33 @@ DEFUN (no_debug_ospf_sr,
return CMD_SUCCESS;
}
+DEFUN (debug_ospf_default_info,
+ debug_ospf_default_info_cmd,
+ "debug ospf default-information",
+ DEBUG_STR
+ OSPF_STR
+ "OSPF default information\n")
+{
+ if (vty->node == CONFIG_NODE)
+ CONF_DEBUG_ON(defaultinfo, DEFAULTINFO);
+ TERM_DEBUG_ON(defaultinfo, DEFAULTINFO);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_debug_ospf_default_info,
+ no_debug_ospf_default_info_cmd,
+ "no debug ospf default-information",
+ NO_STR
+ DEBUG_STR
+ OSPF_STR
+ "OSPF default information\n")
+{
+ if (vty->node == CONFIG_NODE)
+ CONF_DEBUG_OFF(defaultinfo, DEFAULTINFO);
+ TERM_DEBUG_OFF(defaultinfo, DEFAULTINFO);
+ return CMD_SUCCESS;
+}
+
DEFUN (no_debug_ospf,
no_debug_ospf_cmd,
"no debug ospf",
@@ -1475,6 +1504,7 @@ DEFUN (no_debug_ospf,
DEBUG_OFF(zebra, ZEBRA);
DEBUG_OFF(zebra, ZEBRA_INTERFACE);
DEBUG_OFF(zebra, ZEBRA_REDISTRIBUTE);
+ DEBUG_OFF(defaultinfo, DEFAULTINFO);
for (i = 0; i < 5; i++)
DEBUG_PACKET_OFF(i, flag);
@@ -1501,6 +1531,7 @@ DEFUN (no_debug_ospf,
TERM_DEBUG_OFF(zebra, ZEBRA);
TERM_DEBUG_OFF(zebra, ZEBRA_INTERFACE);
TERM_DEBUG_OFF(zebra, ZEBRA_REDISTRIBUTE);
+ TERM_DEBUG_OFF(defaultinfo, DEFAULTINFO);
return CMD_SUCCESS;
}
@@ -1595,6 +1626,9 @@ static int show_debugging_ospf_common(struct vty *vty, struct ospf *ospf)
" OSPF Zebra redistribute debugging is on\n");
}
+ if (IS_DEBUG_OSPF(defaultinfo, DEFAULTINFO) == OSPF_DEBUG_DEFAULTINFO)
+ vty_out(vty, "OSPF default information is on\n");
+
/* Show debug status for NSSA. */
if (IS_DEBUG_OSPF(nssa, NSSA) == OSPF_DEBUG_NSSA)
vty_out(vty, " OSPF NSSA debugging is on\n");
@@ -1797,6 +1831,7 @@ void ospf_debug_init(void)
install_element(ENABLE_NODE, &debug_ospf_nssa_cmd);
install_element(ENABLE_NODE, &debug_ospf_te_cmd);
install_element(ENABLE_NODE, &debug_ospf_sr_cmd);
+ install_element(ENABLE_NODE, &debug_ospf_default_info_cmd);
install_element(ENABLE_NODE, &no_debug_ospf_ism_cmd);
install_element(ENABLE_NODE, &no_debug_ospf_nsm_cmd);
install_element(ENABLE_NODE, &no_debug_ospf_lsa_cmd);
@@ -1805,6 +1840,7 @@ void ospf_debug_init(void)
install_element(ENABLE_NODE, &no_debug_ospf_nssa_cmd);
install_element(ENABLE_NODE, &no_debug_ospf_te_cmd);
install_element(ENABLE_NODE, &no_debug_ospf_sr_cmd);
+ install_element(ENABLE_NODE, &no_debug_ospf_default_info_cmd);
install_element(ENABLE_NODE, &show_debugging_ospf_instance_cmd);
install_element(ENABLE_NODE, &debug_ospf_packet_cmd);
@@ -1834,6 +1870,7 @@ void ospf_debug_init(void)
install_element(CONFIG_NODE, &debug_ospf_nssa_cmd);
install_element(CONFIG_NODE, &debug_ospf_te_cmd);
install_element(CONFIG_NODE, &debug_ospf_sr_cmd);
+ install_element(CONFIG_NODE, &debug_ospf_default_info_cmd);
install_element(CONFIG_NODE, &no_debug_ospf_nsm_cmd);
install_element(CONFIG_NODE, &no_debug_ospf_lsa_cmd);
install_element(CONFIG_NODE, &no_debug_ospf_zebra_cmd);
@@ -1841,6 +1878,7 @@ void ospf_debug_init(void)
install_element(CONFIG_NODE, &no_debug_ospf_nssa_cmd);
install_element(CONFIG_NODE, &no_debug_ospf_te_cmd);
install_element(CONFIG_NODE, &no_debug_ospf_sr_cmd);
+ install_element(CONFIG_NODE, &no_debug_ospf_default_info_cmd);
install_element(CONFIG_NODE, &debug_ospf_instance_nsm_cmd);
install_element(CONFIG_NODE, &debug_ospf_instance_lsa_cmd);
diff --git a/ospfd/ospf_dump.h b/ospfd/ospf_dump.h
index 6b2ebb125..8c01977ff 100644
--- a/ospfd/ospf_dump.h
+++ b/ospfd/ospf_dump.h
@@ -59,6 +59,7 @@
#define OSPF_DEBUG_TE 0x04
#define OSPF_DEBUG_EXT 0x08
#define OSPF_DEBUG_SR 0x10
+#define OSPF_DEBUG_DEFAULTINFO 0x20
/* Macro for setting debug option. */
#define CONF_DEBUG_PACKET_ON(a, b) conf_debug_ospf_packet[a] |= (b)
@@ -104,6 +105,8 @@
#define IS_DEBUG_OSPF_SR IS_DEBUG_OSPF(sr, SR)
+#define IS_DEBUG_OSPF_DEFAULT_INFO IS_DEBUG_OSPF(defaultinfo, DEFAULTINFO)
+
#define IS_CONF_DEBUG_OSPF_PACKET(a, b) \
(conf_debug_ospf_packet[a] & OSPF_DEBUG_##b)
#define IS_CONF_DEBUG_OSPF(a, b) (conf_debug_ospf_##a & OSPF_DEBUG_##b)
@@ -122,6 +125,7 @@ extern unsigned long term_debug_ospf_nssa;
extern unsigned long term_debug_ospf_te;
extern unsigned long term_debug_ospf_ext;
extern unsigned long term_debug_ospf_sr;
+extern unsigned long term_debug_ospf_defaultinfo;
/* Message Strings. */
extern char *ospf_lsa_type_str[];
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index d089ea76c..07feb2482 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -2032,18 +2032,22 @@ struct ospf_lsa *ospf_external_lsa_originate(struct ospf *ospf,
static struct external_info *ospf_default_external_info(struct ospf *ospf)
{
int type;
- struct route_node *rn;
struct prefix_ipv4 p;
+ struct external_info *default_ei;
+ int ret = 0;
p.family = AF_INET;
p.prefix.s_addr = 0;
p.prefixlen = 0;
+ default_ei = ospf_external_info_lookup(ospf, DEFAULT_ROUTE,
+ ospf->instance, &p);
+ if (!default_ei)
+ return NULL;
+
/* First, lookup redistributed default route. */
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
struct list *ext_list;
- struct listnode *node;
- struct ospf_external *ext;
if (type == ZEBRA_ROUTE_OSPF)
continue;
@@ -2052,17 +2056,10 @@ static struct external_info *ospf_default_external_info(struct ospf *ospf)
if (!ext_list)
continue;
- for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) {
- rn = route_node_lookup(ext->external_info,
- (struct prefix *)&p);
- if (rn != NULL) {
- route_unlock_node(rn);
- assert(rn->info);
- if (ospf_redistribute_check(ospf, rn->info,
- NULL))
- return rn->info;
- }
- }
+ ret = ospf_external_default_routemap_apply_walk(ospf, ext_list,
+ default_ei);
+ if (ret)
+ return default_ei;
}
return NULL;
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index 644ea7f92..04b500d66 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -56,6 +56,7 @@ DEFINE_MTYPE_STATIC(OSPFD, OSPF_EXTERNAL, "OSPF External route table")
DEFINE_MTYPE_STATIC(OSPFD, OSPF_REDISTRIBUTE, "OSPF Redistriute")
DEFINE_MTYPE_STATIC(OSPFD, OSPF_DIST_ARGS, "OSPF Distribute arguments")
+
/* Zebra structure to hold current status. */
struct zclient *zclient = NULL;
@@ -397,6 +398,101 @@ struct ospf_external *ospf_external_add(struct ospf *ospf, uint8_t type,
return ext;
}
+/*
+ * Walk all the ei received from zebra for a route type and apply
+ * default route-map.
+ */
+bool ospf_external_default_routemap_apply_walk(struct ospf *ospf,
+ struct list *ext_list,
+ struct external_info *default_ei)
+{
+ struct listnode *node;
+ struct ospf_external *ext;
+ struct route_node *rn;
+ struct external_info *ei = NULL;
+ int ret = 0;
+
+ for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) {
+ if (!ext->external_info)
+ continue;
+
+ for (rn = route_top(ext->external_info); rn;
+ rn = route_next(rn)) {
+ ei = rn->info;
+ if (!ei)
+ continue;
+ ret = ospf_external_info_apply_default_routemap(
+ ospf, ei, default_ei);
+ if (ret)
+ break;
+ }
+ }
+
+ if (ret && ei) {
+ if (IS_DEBUG_OSPF_DEFAULT_INFO)
+ zlog_debug("Default originate routemap permit ei: %s",
+ inet_ntoa(ei->p.prefix));
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ * Function to originate or flush default after applying
+ * route-map on all ei.
+ */
+static int ospf_external_lsa_default_routemap_timer(struct thread *thread)
+{
+ struct list *ext_list;
+ struct ospf *ospf = THREAD_ARG(thread);
+ struct prefix_ipv4 p;
+ int type;
+ int ret = 0;
+ struct ospf_lsa *lsa;
+ struct external_info *default_ei;
+
+ p.family = AF_INET;
+ p.prefixlen = 0;
+ p.prefix.s_addr = INADDR_ANY;
+
+ /* Get the default extenal info. */
+ default_ei = ospf_external_info_lookup(ospf, DEFAULT_ROUTE,
+ ospf->instance, &p);
+ if (!default_ei) {
+ /* Nothing to be done here. */
+ if (IS_DEBUG_OSPF_DEFAULT_INFO)
+ zlog_debug("Default originate info not present");
+ return 0;
+ }
+
+ /* For all the ei apply route-map */
+ for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
+ ext_list = ospf->external[type];
+ if (!ext_list || type == ZEBRA_ROUTE_OSPF)
+ continue;
+
+ ret = ospf_external_default_routemap_apply_walk(ospf, ext_list,
+ default_ei);
+ if (ret)
+ break;
+ }
+
+ /* Get the default LSA. */
+ lsa = ospf_external_info_find_lsa(ospf, &p);
+
+ /* If permit then originate default. */
+ if (ret && !lsa)
+ ospf_external_lsa_originate(ospf, default_ei);
+ else if (ret && lsa && IS_LSA_MAXAGE(lsa))
+ ospf_external_lsa_refresh(ospf, lsa, default_ei, true);
+ else if (!ret && lsa)
+ ospf_external_lsa_flush(ospf, DEFAULT_ROUTE, &default_ei->p, 0);
+
+ return 1;
+}
+
+
void ospf_external_del(struct ospf *ospf, uint8_t type, unsigned short instance)
{
struct ospf_external *ext;
@@ -414,6 +510,12 @@ void ospf_external_del(struct ospf *ospf, uint8_t type, unsigned short instance)
XFREE(MTYPE_OSPF_EXTERNAL, ext);
}
+
+ /*
+ * Check if default needs to be flushed too.
+ */
+ thread_add_event(master, ospf_external_lsa_default_routemap_timer, ospf,
+ 0, &ospf->t_default_routemap_timer);
}
/* Update NHLFE for Prefix SID */
@@ -801,6 +903,132 @@ int ospf_distribute_check_connected(struct ospf *ospf, struct external_info *ei)
return 1;
}
+
+/* Apply default route-map on ei received. */
+int ospf_external_info_apply_default_routemap(struct ospf *ospf,
+ struct external_info *ei,
+ struct external_info *default_ei)
+{
+ struct ospf_redist *red;
+ int type = default_ei->type;
+ struct prefix_ipv4 *p = &ei->p;
+ struct route_map_set_values save_values;
+
+
+ if (!ospf_external_lsa_originate_check(ospf, default_ei))
+ return 0;
+
+ save_values = default_ei->route_map_set;
+ ospf_reset_route_map_set_values(&default_ei->route_map_set);
+
+ /* apply route-map if needed */
+ red = ospf_redist_lookup(ospf, type, ospf->instance);
+ if (red && ROUTEMAP_NAME(red)) {
+ route_map_result_t ret;
+
+ ret = route_map_apply(ROUTEMAP(red), (struct prefix *)p,
+ RMAP_OSPF, ei);
+
+ if (ret == RMAP_DENYMATCH) {
+ ei->route_map_set = save_values;
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+
+/*
+ * Default originated is based on route-map condition then
+ * apply route-map on received external info. Originate or
+ * flush based on route-map condition.
+ */
+static bool ospf_external_lsa_default_routemap_apply(struct ospf *ospf,
+ struct external_info *ei,
+ int cmd)
+{
+ struct external_info *default_ei;
+ struct prefix_ipv4 p;
+ struct ospf_lsa *lsa;
+ int ret;
+
+ p.family = AF_INET;
+ p.prefixlen = 0;
+ p.prefix.s_addr = INADDR_ANY;
+
+
+ /* Get the default extenal info. */
+ default_ei = ospf_external_info_lookup(ospf, DEFAULT_ROUTE,
+ ospf->instance, &p);
+ if (!default_ei) {
+ /* Nothing to be done here. */
+ return false;
+ }
+
+ if (IS_DEBUG_OSPF_DEFAULT_INFO)
+ zlog_debug("Apply default originate routemap on ei: %s cmd: %d",
+ inet_ntoa(ei->p.prefix), cmd);
+
+ ret = ospf_external_info_apply_default_routemap(ospf, ei, default_ei);
+
+ /* If deny then nothing to be done both in add and del case. */
+ if (!ret) {
+ if (IS_DEBUG_OSPF_DEFAULT_INFO)
+ zlog_debug("Default originte routemap deny for ei: %s",
+ inet_ntoa(ei->p.prefix));
+ return false;
+ }
+
+ /* Get the default LSA. */
+ lsa = ospf_external_info_find_lsa(ospf, &p);
+
+ /* If this is add route and permit then ooriginate default. */
+ if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD) {
+ /* If permit and default already advertise then return. */
+ if (lsa && !IS_LSA_MAXAGE(lsa)) {
+ if (IS_DEBUG_OSPF_DEFAULT_INFO)
+ zlog_debug("Defult lsa already originated");
+ return true;
+ }
+
+ if (IS_DEBUG_OSPF_DEFAULT_INFO)
+ zlog_debug("Originating/Refreshing default lsa");
+
+ if (lsa && IS_LSA_MAXAGE(lsa))
+ /* Refresh lsa.*/
+ ospf_external_lsa_refresh(ospf, lsa, default_ei, true);
+ else
+ /* If permit and default not advertised then advertise.
+ */
+ ospf_external_lsa_originate(ospf, default_ei);
+
+ } else if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_DEL) {
+ /* If deny and lsa is not originated then nothing to be done.*/
+ if (!lsa) {
+ if (IS_DEBUG_OSPF_DEFAULT_INFO)
+ zlog_debug(
+ "Default lsa not originated, not flushing");
+ return true;
+ }
+
+ if (IS_DEBUG_OSPF_DEFAULT_INFO)
+ zlog_debug(
+ "Running default route-map again as ei: %s deleted",
+ inet_ntoa(ei->p.prefix));
+ /*
+ * if this route delete was permitted then we need to check
+ * there are any other external info which can still trigger
+ * default route origination else flush it.
+ */
+ thread_add_event(master,
+ ospf_external_lsa_default_routemap_timer, ospf,
+ 0, &ospf->t_default_routemap_timer);
+ }
+
+ return true;
+}
+
/* return 1 if external LSA must be originated, 0 otherwise */
int ospf_redistribute_check(struct ospf *ospf, struct external_info *ei,
int *changed)
@@ -812,6 +1040,10 @@ int ospf_redistribute_check(struct ospf *ospf, struct external_info *ei,
unsigned short instance = is_prefix_default(&ei->p) ? 0 : ei->instance;
route_tag_t saved_tag = 0;
+ /* Default is handled differently. */
+ if (type == DEFAULT_ROUTE)
+ return 1;
+
if (changed)
*changed = 0;
@@ -1004,8 +1236,24 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS)
}
}
}
+
+ /*
+ * Check if default-information originate is
+ * with some routemap prefix/access list match.
+ */
+ ospf_external_lsa_default_routemap_apply(ospf, ei, cmd);
+
} else /* if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_DEL) */
{
+ /*
+ * Check if default-information originate is
+ * with some routemap prefix/access list match.
+ * Apply before ei is deleted.
+ */
+ ei = ospf_external_info_lookup(ospf, rt_type, api.instance, &p);
+ if (ei)
+ ospf_external_lsa_default_routemap_apply(ospf, ei, cmd);
+
ospf_external_info_delete(ospf, rt_type, api.instance, p);
if (is_prefix_default(&p))
ospf_external_lsa_refresh_default(ospf);
@@ -1014,6 +1262,7 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS)
ifindex /*, nexthop */);
}
+
return 0;
}
diff --git a/ospfd/ospf_zebra.h b/ospfd/ospf_zebra.h
index 253d2e0a3..80abf6236 100644
--- a/ospfd/ospf_zebra.h
+++ b/ospfd/ospf_zebra.h
@@ -92,5 +92,10 @@ extern int ospf_distance_unset(struct vty *, struct ospf *, const char *,
extern void ospf_zebra_init(struct thread_master *, unsigned short);
extern void ospf_zebra_vrf_register(struct ospf *ospf);
extern void ospf_zebra_vrf_deregister(struct ospf *ospf);
-
+bool ospf_external_default_routemap_apply_walk(
+ struct ospf *ospf, struct list *ext_list,
+ struct external_info *default_ei);
+int ospf_external_info_apply_default_routemap(struct ospf *ospf,
+ struct external_info *ei,
+ struct external_info *default_ei);
#endif /* _ZEBRA_OSPF_ZEBRA_H */
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index ea9c7c58c..f9cc474d5 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -686,6 +686,7 @@ static void ospf_finish_final(struct ospf *ospf)
OSPF_TIMER_OFF(ospf->t_lsa_refresher);
OSPF_TIMER_OFF(ospf->t_opaque_lsa_self);
OSPF_TIMER_OFF(ospf->t_sr_update);
+ OSPF_TIMER_OFF(ospf->t_default_routemap_timer);
LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa)
ospf_discard_from_db(ospf, ospf->lsdb, lsa);
diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h
index 5e91e6f8e..cdeaa38dc 100644
--- a/ospfd/ospfd.h
+++ b/ospfd/ospfd.h
@@ -249,6 +249,8 @@ struct ospf {
struct thread *t_write;
#define OSPF_WRITE_INTERFACE_COUNT_DEFAULT 20
+ struct thread *t_default_routemap_timer;
+
int write_oi_count; /* Num of packets sent per thread invocation */
struct thread *t_read;
int fd;
diff --git a/tests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py b/tests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py
index 087ba21e5..948f641af 100755
--- a/tests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py
+++ b/tests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py
@@ -63,7 +63,7 @@ from lib.common_config import (
reset_config_on_routers,
)
from lib.topolog import logger
-from lib.bgp import verify_bgp_convergence, create_router_bgp, clear_bgp_and_verify
+from lib.bgp import verify_bgp_convergence, create_router_bgp, clear_bgp
from lib.topojson import build_topo_from_json, build_config_from_json
# Reading the data from JSON File for topology and configuration creation
@@ -295,7 +295,7 @@ def test_modify_ecmp_max_paths(request, ecmp_num, test_type):
addr_type,
dut,
input_dict_1,
- next_hop=NEXT_HOPS[addr_type][:int(ecmp_num)],
+ next_hop=NEXT_HOPS[addr_type][: int(ecmp_num)],
protocol=protocol,
)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
@@ -336,8 +336,12 @@ def test_ecmp_after_clear_bgp(request, test_type):
tc_name, result
)
- # Clear bgp
- result = clear_bgp_and_verify(tgen, topo, dut)
+ # Clear BGP
+ for addr_type in ADDR_TYPES:
+ clear_bgp(tgen, addr_type, dut)
+
+ # Verify BGP convergence
+ result = verify_bgp_convergence(tgen, topo)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
for addr_type in ADDR_TYPES:
diff --git a/tests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py b/tests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py
index 94409ff3e..5b997fdd1 100755
--- a/tests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py
+++ b/tests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py
@@ -63,7 +63,7 @@ from lib.common_config import (
reset_config_on_routers,
)
from lib.topolog import logger
-from lib.bgp import verify_bgp_convergence, create_router_bgp, clear_bgp_and_verify
+from lib.bgp import verify_bgp_convergence, create_router_bgp, clear_bgp
from lib.topojson import build_topo_from_json, build_config_from_json
# Reading the data from JSON File for topology and configuration creation
@@ -296,7 +296,7 @@ def test_modify_ecmp_max_paths(request, ecmp_num, test_type):
addr_type,
dut,
input_dict_1,
- next_hop=NEXT_HOPS[addr_type][:int(ecmp_num)],
+ next_hop=NEXT_HOPS[addr_type][: int(ecmp_num)],
protocol=protocol,
)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
@@ -337,8 +337,12 @@ def test_ecmp_after_clear_bgp(request, test_type):
tc_name, result
)
- # Clear bgp
- result = clear_bgp_and_verify(tgen, topo, dut)
+ # Clear BGP
+ for addr_type in ADDR_TYPES:
+ clear_bgp(tgen, addr_type, dut)
+
+ # Verify BGP convergence
+ result = verify_bgp_convergence(tgen, topo)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
for addr_type in ADDR_TYPES:
diff --git a/tests/topotests/lib/bgp.py b/tests/topotests/lib/bgp.py
index 44b733505..971bbd0f3 100644
--- a/tests/topotests/lib/bgp.py
+++ b/tests/topotests/lib/bgp.py
@@ -44,7 +44,6 @@ from lib.common_config import (
LOGDIR = "/tmp/topotests/"
TMPDIR = None
-
def create_router_bgp(tgen, topo, input_dict=None, build=False, load_config=True):
"""
API to configure bgp on router
@@ -882,7 +881,7 @@ def verify_router_id(tgen, topo, input_dict):
return True
-@retry(attempts=44, wait=3, return_is_str=True)
+@retry(attempts=50, wait=3, return_is_str=True)
def verify_bgp_convergence(tgen, topo, dut=None):
"""
API will verify if BGP is converged with in the given time frame.
@@ -1052,11 +1051,13 @@ def verify_bgp_convergence(tgen, topo, dut=None):
if nh_state == "Established":
no_of_peer += 1
- if no_of_peer == total_peer:
- logger.info("[DUT: %s] VRF: %s, BGP is Converged", router, vrf)
- else:
- errormsg = "[DUT: %s] VRF: %s, BGP is not converged" % (router, vrf)
- return errormsg
+ if no_of_peer == total_peer:
+ logger.info("[DUT: %s] VRF: %s, BGP is Converged for %s address-family",
+ router, vrf, addr_type)
+ else:
+ errormsg = ("[DUT: %s] VRF: %s, BGP is not converged for %s address-family" %
+ (router, vrf, addr_type))
+ return errormsg
logger.debug("Exiting API: verify_bgp_convergence()")
return True
@@ -1326,7 +1327,7 @@ def verify_as_numbers(tgen, topo, input_dict):
return True
-@retry(attempts=44, wait=3, return_is_str=True)
+@retry(attempts=50, wait=3, return_is_str=True)
def verify_bgp_convergence_from_running_config(tgen, dut=None):
"""
API to verify BGP convergence b/w loopback and physical interface.
@@ -1470,7 +1471,7 @@ def clear_bgp_and_verify(tgen, topo, router):
sleeptime = 3
# Verifying BGP convergence before bgp clear command
- for retry in range(44):
+ for retry in range(50):
# Waiting for BGP to converge
logger.info(
"Waiting for %s sec for BGP to converge on router" " %s...",
@@ -1552,7 +1553,7 @@ def clear_bgp_and_verify(tgen, topo, router):
peer_uptime_after_clear_bgp = {}
# Verifying BGP convergence after bgp clear command
- for retry in range(44):
+ for retry in range(50):
# Waiting for BGP to converge
logger.info(
diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py
index fb82b5062..d72d0aa22 100644
--- a/tests/topotests/lib/common_config.py
+++ b/tests/topotests/lib/common_config.py
@@ -690,6 +690,12 @@ def start_topology(tgen):
router_list = tgen.routers()
for rname in ROUTER_LIST:
router = router_list[rname]
+
+ # It will help in debugging the failures, will give more details on which
+ # specific kernel version tests are failing
+ linux_ver = router.run("uname -a")
+ logger.info("Logging platform related details: \n %s \n", linux_ver)
+
try:
os.chdir(TMPDIR)