summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--isisd/isis_adjacency.c41
-rw-r--r--isisd/isis_adjacency.h1
-rw-r--r--isisd/isis_circuit.c34
-rw-r--r--isisd/isis_circuit.h5
-rw-r--r--isisd/isis_lfa.c18
-rw-r--r--isisd/isis_route.c88
-rw-r--r--isisd/isis_route.h5
-rw-r--r--isisd/isis_spf.c27
-rw-r--r--isisd/isis_spf.h4
-rw-r--r--isisd/isisd.c19
-rw-r--r--isisd/isisd.h3
-rw-r--r--tests/isisd/test_isis_spf.refout180
-rw-r--r--tests/topotests/isis_lfa_topo1/rt1/bfdd.conf6
-rw-r--r--tests/topotests/isis_lfa_topo1/rt1/step14/show_ipv6_route.ref.diff0
-rw-r--r--tests/topotests/isis_lfa_topo1/rt1/step15/show_ipv6_route.ref.diff50
-rw-r--r--tests/topotests/isis_lfa_topo1/rt1/step16/show_ipv6_route.ref.diff53
-rw-r--r--tests/topotests/isis_lfa_topo1/rt2/bfdd.conf6
-rwxr-xr-xtests/topotests/isis_lfa_topo1/test_isis_lfa_topo1.py398
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt1/step10/show_ip_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt1/step10/show_ipv6_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt1/step10/show_mpls_table.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt1/step11/show_ip_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt1/step11/show_ipv6_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt1/step11/show_mpls_table.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt1/step12/show_ip_route.ref.diff19
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt1/step12/show_ipv6_route.ref.diff18
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt1/step12/show_mpls_table.ref.diff28
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt2/step10/show_ip_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt2/step10/show_ipv6_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt2/step10/show_mpls_table.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt2/step11/show_ip_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt2/step11/show_ipv6_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt2/step11/show_mpls_table.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt2/step12/show_ip_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt2/step12/show_ipv6_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt2/step12/show_mpls_table.ref.diff20
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt3/step10/show_ip_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt3/step10/show_ipv6_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt3/step10/show_mpls_table.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt3/step11/show_ip_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt3/step11/show_ipv6_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt3/step11/show_mpls_table.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt3/step12/show_ip_route.ref.diff58
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt3/step12/show_ipv6_route.ref.diff45
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt3/step12/show_mpls_table.ref.diff60
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt4/step10/show_ip_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt4/step10/show_ipv6_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt4/step10/show_mpls_table.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt4/step11/show_ip_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt4/step11/show_ipv6_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt4/step11/show_mpls_table.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt4/step12/show_ip_route.ref.diff144
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt4/step12/show_ipv6_route.ref.diff50
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt4/step12/show_mpls_table.ref.diff78
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt5/bfdd.conf14
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt5/step10/show_ip_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt5/step10/show_ipv6_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt5/step10/show_mpls_table.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt5/step11/show_ip_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt5/step11/show_ipv6_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt5/step11/show_mpls_table.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt5/step12/show_ip_route.ref.diff151
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt5/step12/show_ipv6_route.ref.diff53
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt5/step12/show_mpls_table.ref.diff80
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt6/bfdd.conf14
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt6/step10/show_ip_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt6/step10/show_ipv6_route.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt6/step10/show_mpls_table.ref.diff0
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt6/step11/show_ip_route.ref.diff125
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt6/step11/show_ipv6_route.ref.diff56
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt6/step11/show_mpls_table.ref.diff106
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt6/step12/show_ip_route.ref.diff153
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt6/step12/show_ipv6_route.ref.diff66
-rw-r--r--tests/topotests/isis_tilfa_topo1/rt6/step12/show_mpls_table.ref.diff78
-rwxr-xr-xtests/topotests/isis_tilfa_topo1/test_isis_tilfa_topo1.py370
75 files changed, 2601 insertions, 123 deletions
diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c
index 11f17ec7bf..1b85299adf 100644
--- a/isisd/isis_adjacency.c
+++ b/isisd/isis_adjacency.c
@@ -212,6 +212,36 @@ static const char *adj_level2string(int level)
return NULL; /* not reached */
}
+static void isis_adj_route_switchover(struct isis_adjacency *adj)
+{
+ union g_addr ip = {};
+ ifindex_t ifindex;
+ unsigned int i;
+
+ if (!adj->circuit || !adj->circuit->interface)
+ return;
+
+ ifindex = adj->circuit->interface->ifindex;
+
+ for (i = 0; i < adj->ipv4_address_count; i++) {
+ ip.ipv4 = adj->ipv4_addresses[i];
+ isis_circuit_switchover_routes(adj->circuit, AF_INET, &ip,
+ ifindex);
+ }
+
+ for (i = 0; i < adj->ll_ipv6_count; i++) {
+ ip.ipv6 = adj->ll_ipv6_addrs[i];
+ isis_circuit_switchover_routes(adj->circuit, AF_INET6, &ip,
+ ifindex);
+ }
+
+ for (i = 0; i < adj->global_ipv6_count; i++) {
+ ip.ipv6 = adj->global_ipv6_addrs[i];
+ isis_circuit_switchover_routes(adj->circuit, AF_INET6, &ip,
+ ifindex);
+ }
+}
+
void isis_adj_process_threeway(struct isis_adjacency *adj,
struct isis_threeway_adj *tw_adj,
enum isis_adj_usage adj_usage)
@@ -298,6 +328,17 @@ void isis_adj_state_change(struct isis_adjacency **padj,
if (new_state == old_state)
return;
+ if (old_state == ISIS_ADJ_UP &&
+ !CHECK_FLAG(adj->circuit->flags, ISIS_CIRCUIT_IF_DOWN_FROM_Z)) {
+ if (IS_DEBUG_EVENTS)
+ zlog_debug(
+ "ISIS-Adj (%s): Starting fast-reroute on state change "
+ "%d->%d: %s",
+ circuit->area->area_tag, old_state, new_state,
+ reason ? reason : "unspecified");
+ isis_adj_route_switchover(adj);
+ }
+
adj->adj_state = new_state;
send_hello_sched(circuit, adj->level, TRIGGERED_IIH_DELAY);
diff --git a/isisd/isis_adjacency.h b/isisd/isis_adjacency.h
index 7467a619cb..49adc89ae5 100644
--- a/isisd/isis_adjacency.h
+++ b/isisd/isis_adjacency.h
@@ -151,5 +151,4 @@ void isis_adj_build_up_list(struct list *adjdb, struct list *list);
int isis_adj_usage2levels(enum isis_adj_usage usage);
void isis_bfd_startup_timer(struct thread *thread);
const char *isis_adj_name(const struct isis_adjacency *adj);
-
#endif /* ISIS_ADJACENCY_H */
diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c
index 28d4b530fc..26e1de20f7 100644
--- a/isisd/isis_circuit.c
+++ b/isisd/isis_circuit.c
@@ -593,6 +593,27 @@ size_t isis_circuit_pdu_size(struct isis_circuit *circuit)
return ISO_MTU(circuit);
}
+static bool isis_circuit_lfa_enabled(struct isis_circuit *circuit, int level)
+{
+ return (circuit->lfa_protection[level - 1] ||
+ circuit->rlfa_protection[level - 1] ||
+ circuit->tilfa_protection[level - 1]);
+}
+
+void isis_circuit_switchover_routes(struct isis_circuit *circuit, int family,
+ union g_addr *nexthop_ip, ifindex_t ifindex)
+{
+ char is_type = circuit->area->is_type;
+ if ((is_type == IS_LEVEL_1 || is_type == IS_LEVEL_1_AND_2) &&
+ isis_circuit_lfa_enabled(circuit, IS_LEVEL_1))
+ isis_area_switchover_routes(circuit->area, family, nexthop_ip,
+ ifindex, IS_LEVEL_1);
+ if ((is_type == IS_LEVEL_2 || is_type == IS_LEVEL_1_AND_2) &&
+ isis_circuit_lfa_enabled(circuit, IS_LEVEL_2))
+ isis_area_switchover_routes(circuit->area, family, nexthop_ip,
+ ifindex, IS_LEVEL_2);
+}
+
void isis_circuit_stream(struct isis_circuit *circuit, struct stream **stream)
{
size_t stream_size = isis_circuit_pdu_size(circuit);
@@ -1597,17 +1618,26 @@ static int isis_ifp_up(struct interface *ifp)
{
struct isis_circuit *circuit = ifp->info;
- if (circuit)
+ if (circuit) {
+ UNSET_FLAG(circuit->flags, ISIS_CIRCUIT_IF_DOWN_FROM_Z);
isis_csm_state_change(IF_UP_FROM_Z, circuit, ifp);
+ }
return 0;
}
static int isis_ifp_down(struct interface *ifp)
{
+ afi_t afi;
struct isis_circuit *circuit = ifp->info;
- if (circuit) {
+ if (circuit &&
+ !CHECK_FLAG(circuit->flags, ISIS_CIRCUIT_IF_DOWN_FROM_Z)) {
+ SET_FLAG(circuit->flags, ISIS_CIRCUIT_IF_DOWN_FROM_Z);
+ for (afi = AFI_IP; afi <= AFI_IP6; afi++)
+ isis_circuit_switchover_routes(
+ circuit, afi == AFI_IP ? AF_INET : AF_INET6,
+ NULL, ifp->ifindex);
isis_csm_state_change(IF_DOWN_FROM_Z, circuit, ifp);
SET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF);
diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h
index 5ff0390c26..b3ad3f7ffe 100644
--- a/isisd/isis_circuit.h
+++ b/isisd/isis_circuit.h
@@ -28,6 +28,7 @@
#include "qobj.h"
#include "prefix.h"
#include "ferr.h"
+#include "nexthop.h"
#include "isis_constants.h"
#include "isis_common.h"
@@ -141,6 +142,7 @@ struct isis_circuit {
struct list *ipv6_non_link; /* our non-link local IPv6 addresses */
uint16_t upadjcount[ISIS_LEVELS];
#define ISIS_CIRCUIT_FLAPPED_AFTER_SPF 0x01
+#define ISIS_CIRCUIT_IF_DOWN_FROM_Z 0x02
uint8_t flags;
bool disable_threeway_adj;
struct {
@@ -209,6 +211,9 @@ void isis_circuit_print_vty(struct isis_circuit *circuit, struct vty *vty,
void isis_circuit_print_json(struct isis_circuit *circuit,
struct json_object *json, char detail);
size_t isis_circuit_pdu_size(struct isis_circuit *circuit);
+void isis_circuit_switchover_routes(struct isis_circuit *circuit, int family,
+ union g_addr *nexthop_ip,
+ ifindex_t ifindex);
void isis_circuit_stream(struct isis_circuit *circuit, struct stream **stream);
void isis_circuit_af_set(struct isis_circuit *circuit, bool ip_router,
diff --git a/isisd/isis_lfa.c b/isisd/isis_lfa.c
index 800cac8521..b348c876d3 100644
--- a/isisd/isis_lfa.c
+++ b/isisd/isis_lfa.c
@@ -1836,7 +1836,7 @@ static bool clfa_loop_free_check(struct isis_spftree *spftree,
struct isis_vertex *vertex_S_D,
struct isis_spf_adj *sadj_primary,
struct isis_spf_adj *sadj_N,
- uint32_t *lfa_metric)
+ uint32_t *path_metric)
{
struct isis_spf_node *node_N;
uint32_t dist_N_D;
@@ -1882,7 +1882,7 @@ static bool clfa_loop_free_check(struct isis_spftree *spftree,
dist_N_S, dist_S_D);
if (dist_N_D < (dist_N_S + dist_S_D)) {
- *lfa_metric = sadj_N->metric + dist_N_D;
+ *path_metric = sadj_N->metric + dist_N_D;
return true;
}
@@ -2082,7 +2082,7 @@ void isis_lfa_compute(struct isis_area *area, struct isis_circuit *circuit,
struct isis_spftree *spftree,
struct lfa_protected_resource *resource)
{
- struct isis_vertex *vertex;
+ struct isis_vertex *vertex, *parent_vertex;
struct listnode *vnode, *snode;
int level = spftree->level;
@@ -2099,7 +2099,7 @@ void isis_lfa_compute(struct isis_area *area, struct isis_circuit *circuit,
struct isis_vertex_adj *vadj_primary;
struct isis_spf_adj *sadj_primary;
bool allow_ecmp;
- uint32_t best_metric = UINT32_MAX;
+ uint32_t prefix_metric, best_metric = UINT32_MAX;
char buf[VID2STR_BUFFER];
if (!VTYPE_IP(vertex->type))
@@ -2133,6 +2133,9 @@ void isis_lfa_compute(struct isis_area *area, struct isis_circuit *circuit,
vadj_primary = listnode_head(vertex->Adj_N);
sadj_primary = vadj_primary->sadj;
+ parent_vertex = listnode_head(vertex->parents);
+ prefix_metric = vertex->d_N - parent_vertex->d_N;
+
/*
* Loop over list of SPF adjacencies and compute a list of
* preliminary LFAs.
@@ -2140,7 +2143,7 @@ void isis_lfa_compute(struct isis_area *area, struct isis_circuit *circuit,
lfa_list = list_new();
lfa_list->del = isis_vertex_adj_free;
for (ALL_LIST_ELEMENTS_RO(spftree->sadj_list, snode, sadj_N)) {
- uint32_t lfa_metric;
+ uint32_t lfa_metric, path_metric;
struct isis_vertex_adj *lfa;
struct isis_prefix_sid *psid = NULL;
bool last_hop = false;
@@ -2190,7 +2193,7 @@ void isis_lfa_compute(struct isis_area *area, struct isis_circuit *circuit,
/* Check loop-free criterion. */
if (!clfa_loop_free_check(spftree, vertex, sadj_primary,
- sadj_N, &lfa_metric)) {
+ sadj_N, &path_metric)) {
if (IS_DEBUG_LFA)
zlog_debug(
"ISIS-LFA: LFA condition not met for %s",
@@ -2198,6 +2201,7 @@ void isis_lfa_compute(struct isis_area *area, struct isis_circuit *circuit,
continue;
}
+ lfa_metric = path_metric + prefix_metric;
if (lfa_metric < best_metric)
best_metric = lfa_metric;
@@ -2208,7 +2212,7 @@ void isis_lfa_compute(struct isis_area *area, struct isis_circuit *circuit,
if (vertex->N.ip.sr.present) {
psid = &vertex->N.ip.sr.sid;
- if (lfa_metric == sadj_N->metric)
+ if (path_metric == sadj_N->metric)
last_hop = true;
}
lfa = isis_vertex_adj_add(spftree, vertex, lfa_list,
diff --git a/isisd/isis_route.c b/isisd/isis_route.c
index 9f8f639e5d..0e7947dd46 100644
--- a/isisd/isis_route.c
+++ b/isisd/isis_route.c
@@ -91,11 +91,17 @@ static struct isis_nexthop *nexthoplookup(struct list *nexthops, int family,
struct isis_nexthop *nh;
for (ALL_LIST_ELEMENTS_RO(nexthops, node, nh)) {
- if (nh->family != family)
- continue;
if (nh->ifindex != ifindex)
continue;
+ /* if the IP is unspecified, return the first nexthop found on
+ * the interface */
+ if (!ip)
+ return nh;
+
+ if (nh->family != family)
+ continue;
+
switch (family) {
case AF_INET:
if (IPV4_ADDR_CMP(&nh->ip.ipv4, &ip->ipv4))
@@ -459,6 +465,21 @@ void isis_route_delete(struct isis_area *area, struct route_node *rode,
route_unlock_node(rode);
}
+static void isis_route_remove_previous_sid(struct isis_area *area,
+ struct prefix *prefix,
+ struct isis_route_info *route_info)
+{
+ /*
+ * Explicitly uninstall previous Prefix-SID label if it has
+ * changed or was removed.
+ */
+ if (route_info->sr_previous.present &&
+ (!route_info->sr.present ||
+ route_info->sr_previous.label != route_info->sr.label))
+ isis_zebra_prefix_sid_uninstall(area, prefix, route_info,
+ &route_info->sr_previous);
+}
+
static void isis_route_update(struct isis_area *area, struct prefix *prefix,
struct prefix_ipv6 *src_p,
struct isis_route_info *route_info)
@@ -467,17 +488,7 @@ static void isis_route_update(struct isis_area *area, struct prefix *prefix,
if (CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
return;
- /*
- * Explicitly uninstall previous Prefix-SID label if it has
- * changed or was removed.
- */
- if (route_info->sr_previous.present
- && (!route_info->sr.present
- || route_info->sr_previous.label
- != route_info->sr.label))
- isis_zebra_prefix_sid_uninstall(
- area, prefix, route_info,
- &route_info->sr_previous);
+ isis_route_remove_previous_sid(area, prefix, route_info);
/* Install route. */
isis_zebra_route_add_route(area->isis, prefix, src_p,
@@ -724,3 +735,54 @@ void isis_route_invalidate_table(struct isis_area *area,
UNSET_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE);
}
}
+
+void isis_route_switchover_nexthop(struct isis_area *area,
+ struct route_table *table, int family,
+ union g_addr *nexthop_addr,
+ ifindex_t ifindex)
+{
+ const char *ifname = NULL, *vrfname = NULL;
+ struct isis_route_info *rinfo;
+ struct prefix_ipv6 *src_p;
+ struct route_node *rnode;
+ vrf_id_t vrf_id;
+ struct prefix *prefix;
+
+ if (IS_DEBUG_EVENTS) {
+ if (area && area->isis) {
+ vrf_id = area->isis->vrf_id;
+ vrfname = vrf_id_to_name(vrf_id);
+ ifname = ifindex2ifname(ifindex, vrf_id);
+ }
+ zlog_debug("%s: initiating fast-reroute %s on VRF %s iface %s",
+ __func__, family2str(family), vrfname ? vrfname : "",
+ ifname ? ifname : "");
+ }
+
+ for (rnode = route_top(table); rnode;
+ rnode = srcdest_route_next(rnode)) {
+ if (!rnode->info)
+ continue;
+ rinfo = rnode->info;
+
+ if (!rinfo->backup)
+ continue;
+
+ if (!nexthoplookup(rinfo->nexthops, family, nexthop_addr,
+ ifindex))
+ continue;
+
+ srcdest_rnode_prefixes(rnode, (const struct prefix **)&prefix,
+ (const struct prefix **)&src_p);
+
+ /* Switchover route. */
+ isis_route_remove_previous_sid(area, prefix, rinfo);
+ UNSET_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
+ isis_route_update(area, prefix, src_p, rinfo->backup);
+
+ isis_route_info_delete(rinfo);
+
+ rnode->info = NULL;
+ route_unlock_node(rnode);
+ }
+}
diff --git a/isisd/isis_route.h b/isisd/isis_route.h
index 0e206d08f4..a0e0500aec 100644
--- a/isisd/isis_route.h
+++ b/isisd/isis_route.h
@@ -86,4 +86,9 @@ void isis_route_invalidate_table(struct isis_area *area,
void isis_route_node_cleanup(struct route_table *table,
struct route_node *node);
+void isis_route_switchover_nexthop(struct isis_area *area,
+ struct route_table *table, int family,
+ union g_addr *nexthop_addr,
+ ifindex_t ifindex);
+
#endif /* _ZEBRA_ISIS_ROUTE_H */
diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c
index 3aef8ada24..d7335e06d1 100644
--- a/isisd/isis_spf.c
+++ b/isisd/isis_spf.c
@@ -1851,6 +1851,15 @@ void isis_spf_invalidate_routes(struct isis_spftree *tree)
tree->route_table_backup->cleanup = isis_route_node_cleanup;
}
+void isis_spf_switchover_routes(struct isis_area *area,
+ struct isis_spftree **trees, int family,
+ union g_addr *nexthop_ip, ifindex_t ifindex,
+ int level)
+{
+ isis_route_switchover_nexthop(area, trees[level - 1]->route_table,
+ family, nexthop_ip, ifindex);
+}
+
static void isis_run_spf_cb(struct thread *thread)
{
struct isis_spf_run *run = THREAD_ARG(thread);
@@ -1922,9 +1931,19 @@ void isis_spf_timer_free(void *run)
int _isis_spf_schedule(struct isis_area *area, int level,
const char *func, const char *file, int line)
{
- struct isis_spftree *spftree = area->spftree[SPFTREE_IPV4][level - 1];
- time_t now = monotime(NULL);
- int diff = now - spftree->last_run_monotime;
+ struct isis_spftree *spftree;
+ time_t now;
+ long tree_diff, diff;
+ int tree;
+
+ now = monotime(NULL);
+ diff = 0;
+ for (tree = SPFTREE_IPV4; tree < SPFTREE_COUNT; tree++) {
+ spftree = area->spftree[tree][level - 1];
+ tree_diff = difftime(now - spftree->last_run_monotime, 0);
+ if (tree_diff != now && (diff == 0 || tree_diff < diff))
+ diff = tree_diff;
+ }
if (CHECK_FLAG(im->options, F_ISIS_UNIT_TEST))
return 0;
@@ -1934,7 +1953,7 @@ int _isis_spf_schedule(struct isis_area *area, int level,
if (IS_DEBUG_SPF_EVENTS) {
zlog_debug(
- "ISIS-SPF (%s) L%d SPF schedule called, lastrun %d sec ago Caller: %s %s:%d",
+ "ISIS-SPF (%s) L%d SPF schedule called, lastrun %ld sec ago Caller: %s %s:%d",
area->area_tag, level, diff, func, file, line);
}
diff --git a/isisd/isis_spf.h b/isisd/isis_spf.h
index 815db7b226..3fa5182baf 100644
--- a/isisd/isis_spf.h
+++ b/isisd/isis_spf.h
@@ -60,6 +60,10 @@ struct isis_vertex *isis_spf_prefix_sid_lookup(struct isis_spftree *spftree,
void isis_spf_invalidate_routes(struct isis_spftree *tree);
void isis_spf_verify_routes(struct isis_area *area,
struct isis_spftree **trees);
+void isis_spf_switchover_routes(struct isis_area *area,
+ struct isis_spftree **trees, int family,
+ union g_addr *nexthop_ip, ifindex_t ifindex,
+ int level);
void isis_spftree_del(struct isis_spftree *spftree);
void spftree_area_init(struct isis_area *area);
void spftree_area_del(struct isis_area *area);
diff --git a/isisd/isisd.c b/isisd/isisd.c
index 996a62f4d5..3a1eff0335 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -3077,6 +3077,25 @@ void isis_area_verify_routes(struct isis_area *area)
isis_spf_verify_routes(area, area->spftree[tree]);
}
+void isis_area_switchover_routes(struct isis_area *area, int family,
+ union g_addr *nexthop_ip, ifindex_t ifindex,
+ int level)
+{
+ int tree;
+
+ /* TODO SPFTREE_DSTSRC */
+ if (family == AF_INET)
+ tree = SPFTREE_IPV4;
+ else if (family == AF_INET6)
+ tree = SPFTREE_IPV6;
+ else
+ return;
+
+ isis_spf_switchover_routes(area, area->spftree[tree], family,
+ nexthop_ip, ifindex, level);
+}
+
+
static void area_resign_level(struct isis_area *area, int level)
{
isis_area_invalidate_routes(area, level);
diff --git a/isisd/isisd.h b/isisd/isisd.h
index c313fd9ef7..a3dbfde6bc 100644
--- a/isisd/isisd.h
+++ b/isisd/isisd.h
@@ -287,6 +287,9 @@ struct isis_lsp *lsp_for_sysid(struct lspdb_head *head, const char *sysid_str,
void isis_area_invalidate_routes(struct isis_area *area, int levels);
void isis_area_verify_routes(struct isis_area *area);
+void isis_area_switchover_routes(struct isis_area *area, int family,
+ union g_addr *nexthop_ip, ifindex_t ifindex,
+ int level);
void isis_area_overload_bit_set(struct isis_area *area, bool overload_bit);
void isis_area_attached_bit_send_set(struct isis_area *area, bool attached_bit);
diff --git a/tests/isisd/test_isis_spf.refout b/tests/isisd/test_isis_spf.refout
index bdd5b2e439..23d41b9e5d 100644
--- a/tests/isisd/test_isis_spf.refout
+++ b/tests/isisd/test_isis_spf.refout
@@ -823,7 +823,7 @@ IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
----------------------------------------------------------
- 10.0.255.2/32 40 - rt2 implicit-null
+ 10.0.255.2/32 50 - rt2 implicit-null
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
@@ -859,7 +859,7 @@ IS-IS L1 IPv6 routing table:
Prefix Metric Interface Nexthop Label(s)
------------------------------------------------------------
- 2001:db8::2/128 40 - rt2 implicit-null
+ 2001:db8::2/128 50 - rt2 implicit-null
test# test isis topology 2 root rt4 lfa system-id rt6
IS-IS paths to level-1 routers that speak IP
@@ -896,7 +896,7 @@ IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------
- 10.0.255.6/32 20 - rt5 16060
+ 10.0.255.6/32 30 - rt5 16060
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
@@ -932,7 +932,7 @@ IS-IS L1 IPv6 routing table:
Prefix Metric Interface Nexthop Label(s)
-------------------------------------------------------
- 2001:db8::6/128 20 - rt5 16061
+ 2001:db8::6/128 30 - rt5 16061
test# test isis topology 3 root rt1 lfa system-id rt2
IS-IS paths to level-1 routers that speak IP
@@ -967,10 +967,10 @@ IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------
- 10.0.255.2/32 20 - rt3 16020
- 10.0.255.4/32 30 - rt3 16040
- 10.0.255.5/32 40 - rt3 16050
- 10.0.255.6/32 40 - rt3 16060
+ 10.0.255.2/32 30 - rt3 16020
+ 10.0.255.4/32 40 - rt3 16040
+ 10.0.255.5/32 50 - rt3 16050
+ 10.0.255.6/32 50 - rt3 16060
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
@@ -1017,7 +1017,7 @@ IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------
- 10.0.255.3/32 20 - rt2 16030
+ 10.0.255.3/32 30 - rt2 16030
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
@@ -1085,17 +1085,17 @@ IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------------
- 10.0.255.2/32 40 - rt2 implicit-null
- 10.0.255.3/32 50 - rt2 16030
- 10.0.255.4/32 60 - rt2 16040
- 10.0.255.5/32 50 - rt2 16050
- 10.0.255.6/32 60 - rt2 16060
- 10.0.255.7/32 70 - rt2 16070
- 10.0.255.8/32 60 - rt2 16080
- 10.0.255.9/32 70 - rt2 16090
- 10.0.255.10/32 80 - rt2 16100
- 10.0.255.11/32 70 - rt2 16110
- 10.0.255.12/32 80 - rt2 16120
+ 10.0.255.2/32 50 - rt2 implicit-null
+ 10.0.255.3/32 60 - rt2 16030
+ 10.0.255.4/32 70 - rt2 16040
+ 10.0.255.5/32 60 - rt2 16050
+ 10.0.255.6/32 70 - rt2 16060
+ 10.0.255.7/32 80 - rt2 16070
+ 10.0.255.8/32 70 - rt2 16080
+ 10.0.255.9/32 80 - rt2 16090
+ 10.0.255.10/32 90 - rt2 16100
+ 10.0.255.11/32 80 - rt2 16110
+ 10.0.255.12/32 90 - rt2 16120
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
@@ -1173,10 +1173,10 @@ IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
------------------------------------------------------
- 10.0.255.8/32 40 - rt10 16080
- 10.0.255.9/32 50 - rt10 16090
- 10.0.255.11/32 30 - rt10 16110
- 10.0.255.12/32 40 - rt10 16120
+ 10.0.255.8/32 50 - rt10 16080
+ 10.0.255.9/32 60 - rt10 16090
+ 10.0.255.11/32 40 - rt10 16110
+ 10.0.255.12/32 50 - rt10 16120
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
@@ -1252,7 +1252,7 @@ IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
------------------------------------------------------
- 10.0.255.10/32 30 - rt7 16100
+ 10.0.255.10/32 40 - rt7 16100
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
@@ -1313,14 +1313,14 @@ IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
----------------------------------------------------------
- 10.0.255.1/32 120 - rt4 16010
- 10.0.255.2/32 110 - rt4 16020
- 10.0.255.4/32 100 - rt4 implicit-null
- 10.0.255.5/32 110 - rt4 16050
- 10.0.255.6/32 130 - rt4 16060
- 10.0.255.7/32 130 - rt4 16070
- 10.0.255.8/32 130 - rt4 16080
- 10.0.255.9/32 120 - rt4 16090
+ 10.0.255.1/32 130 - rt4 16010
+ 10.0.255.2/32 120 - rt4 16020
+ 10.0.255.4/32 110 - rt4 implicit-null
+ 10.0.255.5/32 120 - rt4 16050
+ 10.0.255.6/32 140 - rt4 16060
+ 10.0.255.7/32 140 - rt4 16070
+ 10.0.255.8/32 140 - rt4 16080
+ 10.0.255.9/32 130 - rt4 16090
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
@@ -1366,14 +1366,14 @@ IS-IS L1 IPv6 routing table:
Prefix Metric Interface Nexthop Label(s)
------------------------------------------------------------
- 2001:db8::1/128 120 - rt4 16011
- 2001:db8::2/128 110 - rt4 16021
- 2001:db8::4/128 100 - rt4 implicit-null
- 2001:db8::5/128 110 - rt4 16051
- 2001:db8::6/128 130 - rt4 16061
- 2001:db8::7/128 130 - rt4 16071
- 2001:db8::8/128 130 - rt4 16081
- 2001:db8::9/128 120 - rt4 16091
+ 2001:db8::1/128 130 - rt4 16011
+ 2001:db8::2/128 120 - rt4 16021
+ 2001:db8::4/128 110 - rt4 implicit-null
+ 2001:db8::5/128 120 - rt4 16051
+ 2001:db8::6/128 140 - rt4 16061
+ 2001:db8::7/128 140 - rt4 16071
+ 2001:db8::8/128 140 - rt4 16081
+ 2001:db8::9/128 130 - rt4 16091
test# test isis topology 10 root rt8 lfa system-id rt5
IS-IS paths to level-1 routers that speak IP
@@ -1414,15 +1414,15 @@ IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------
- 10.0.255.1/32 80 - rt6 16010
+ 10.0.255.1/32 90 - rt6 16010
- rt7 16010
- 10.0.255.2/32 90 - rt6 16020
+ 10.0.255.2/32 100 - rt6 16020
- rt7 16020
- 10.0.255.3/32 60 - rt6 16030
+ 10.0.255.3/32 70 - rt6 16030
- rt7 16030
- 10.0.255.4/32 60 - rt6 16040
+ 10.0.255.4/32 70 - rt6 16040
- rt7 16040
- 10.0.255.5/32 100 - rt6 16050
+ 10.0.255.5/32 110 - rt6 16050
- rt7 16050
IS-IS paths to level-1 routers that speak IPv6
@@ -1463,15 +1463,15 @@ IS-IS L1 IPv6 routing table:
Prefix Metric Interface Nexthop Label(s)
-------------------------------------------------------
- 2001:db8::1/128 80 - rt6 16011
+ 2001:db8::1/128 90 - rt6 16011
- rt7 16011
- 2001:db8::2/128 90 - rt6 16021
+ 2001:db8::2/128 100 - rt6 16021
- rt7 16021
- 2001:db8::3/128 60 - rt6 16031
+ 2001:db8::3/128 70 - rt6 16031
- rt7 16031
- 2001:db8::4/128 60 - rt6 16041
+ 2001:db8::4/128 70 - rt6 16041
- rt7 16041
- 2001:db8::5/128 100 - rt6 16051
+ 2001:db8::5/128 110 - rt6 16051
- rt7 16051
test# test isis topology 11 root rt3 lfa system-id rt5
@@ -1511,8 +1511,8 @@ IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------
- 10.0.255.5/32 30 - rt2 16050
- 10.0.255.6/32 30 - rt2 16060
+ 10.0.255.5/32 40 - rt2 16050
+ 10.0.255.6/32 40 - rt2 16060
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
@@ -1550,8 +1550,8 @@ IS-IS L1 IPv6 routing table:
Prefix Metric Interface Nexthop Label(s)
-------------------------------------------------------
- 2001:db8::5/128 30 - rt2 16051
- 2001:db8::6/128 30 - rt2 16061
+ 2001:db8::5/128 40 - rt2 16051
+ 2001:db8::6/128 40 - rt2 16061
test# test isis topology 13 root rt4 lfa system-id rt3
IS-IS paths to level-1 routers that speak IP
@@ -1593,10 +1593,10 @@ IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
----------------------------------------------------------
- 10.0.255.3/32 110 - rt5 16030
- 10.0.255.5/32 100 - rt5 implicit-null
- 10.0.255.6/32 120 - rt5 16060
- 10.0.255.7/32 110 - rt5 16070
+ 10.0.255.3/32 120 - rt5 16030
+ 10.0.255.5/32 110 - rt5 implicit-null
+ 10.0.255.6/32 130 - rt5 16060
+ 10.0.255.7/32 120 - rt5 16070
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
@@ -1699,7 +1699,7 @@ IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------
- 10.0.255.2/32 20 - rt3 -
+ 10.0.255.2/32 30 - rt3 -
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
@@ -1731,7 +1731,7 @@ IS-IS L1 IPv6 routing table:
Prefix Metric Interface Nexthop Label(s)
-------------------------------------------------------
- 2001:db8::2/128 20 - rt3 -
+ 2001:db8::2/128 30 - rt3 -
test# test isis topology 14 root rt5 lfa system-id rt4
IS-IS paths to level-1 routers that speak IP
@@ -1765,10 +1765,10 @@ IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------
- 10.0.255.1/32 60 - rt3 -
- 10.0.255.2/32 60 - rt3 -
- 10.0.255.3/32 50 - rt3 -
- 10.0.255.4/32 60 - rt3 -
+ 10.0.255.1/32 70 - rt3 -
+ 10.0.255.2/32 70 - rt3 -
+ 10.0.255.3/32 60 - rt3 -
+ 10.0.255.4/32 70 - rt3 -
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
@@ -1801,10 +1801,10 @@ IS-IS L1 IPv6 routing table:
Prefix Metric Interface Nexthop Label(s)
-------------------------------------------------------
- 2001:db8::1/128 60 - rt3 -
- 2001:db8::2/128 60 - rt3 -
- 2001:db8::3/128 50 - rt3 -
- 2001:db8::4/128 60 - rt3 -
+ 2001:db8::1/128 70 - rt3 -
+ 2001:db8::2/128 70 - rt3 -
+ 2001:db8::3/128 60 - rt3 -
+ 2001:db8::4/128 70 - rt3 -
test#
test# test isis topology 1 root rt1 remote-lfa system-id rt2
@@ -2174,11 +2174,11 @@ IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------
- 10.0.255.1/32 40 - rt3 16010
+ 10.0.255.1/32 50 - rt3 16010
- rt6 16010
- 10.0.255.2/32 30 - rt3 16020
+ 10.0.255.2/32 40 - rt3 16020
- rt6 16020
- 10.0.255.4/32 20 - rt3 16040
+ 10.0.255.4/32 30 - rt3 16040
- rt6 16040
test# test isis topology 3 root rt5 remote-lfa system-id rt3 ipv4-only
@@ -2535,13 +2535,13 @@ IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
--------------------------------------------------------
- 10.0.255.1/32 50 - rt10 16010
+ 10.0.255.1/32 60 - rt10 16010
10.0.255.2/32 60 - rt12 50900/16020
10.0.255.3/32 70 - rt12 50900/16030
- 10.0.255.4/32 40 - rt10 16040
+ 10.0.255.4/32 50 - rt10 16040
10.0.255.5/32 50 - rt12 50900/16050
10.0.255.6/32 60 - rt12 50900/16060
- 10.0.255.7/32 30 - rt10 16070
+ 10.0.255.7/32 40 - rt10 16070
10.0.255.8/32 40 - rt12 50900/16080
test# test isis topology 7 root rt6 remote-lfa system-id rt5 ipv4-only
@@ -2671,13 +2671,13 @@ IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
------------------------------------------------------
- 10.0.255.1/32 70 - rt9 16010
- 10.0.255.4/32 60 - rt9 16040
- 10.0.255.5/32 50 - rt9 16050
- 10.0.255.7/32 50 - rt9 16070
- 10.0.255.8/32 40 - rt9 16080
- 10.0.255.10/32 60 - rt9 16100
- 10.0.255.11/32 50 - rt9 16110
+ 10.0.255.1/32 80 - rt9 16010
+ 10.0.255.4/32 70 - rt9 16040
+ 10.0.255.5/32 60 - rt9 16050
+ 10.0.255.7/32 60 - rt9 16070
+ 10.0.255.8/32 50 - rt9 16080
+ 10.0.255.10/32 70 - rt9 16100
+ 10.0.255.11/32 60 - rt9 16110
test# test isis topology 8 root rt2 remote-lfa system-id rt5 ipv4-only
P-space (self):
@@ -2863,14 +2863,14 @@ IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
----------------------------------------------------------
- 10.0.255.1/32 50 - rt1 implicit-null
+ 10.0.255.1/32 60 - rt1 implicit-null
- rt3 16010
- 10.0.255.3/32 50 - rt1 16030
+ 10.0.255.3/32 60 - rt1 16030
- rt3 implicit-null
10.0.255.4/32 80 - rt3 50500/16040
- 10.0.255.5/32 60 - rt1 16050
+ 10.0.255.5/32 70 - rt1 16050
- rt3 16050
- 10.0.255.6/32 70 - rt3 16060
+ 10.0.255.6/32 80 - rt3 16060
P-space (self):
@@ -2941,14 +2941,14 @@ IS-IS L1 IPv6 routing table:
Prefix Metric Interface Nexthop Label(s)
------------------------------------------------------------
- 2001:db8::1/128 50 - rt1 implicit-null
+ 2001:db8::1/128 60 - rt1 implicit-null
- rt3 16011
- 2001:db8::3/128 50 - rt1 16031
+ 2001:db8::3/128 60 - rt1 16031
- rt3 implicit-null
2001:db8::4/128 80 - rt3 50500/16041
- 2001:db8::5/128 60 - rt1 16051
+ 2001:db8::5/128 70 - rt1 16051
- rt3 16051
- 2001:db8::6/128 70 - rt3 16061
+ 2001:db8::6/128 80 - rt3 16061
test# test isis topology 13 root rt1 remote-lfa system-id rt3 ipv4-only
P-space (self):
diff --git a/tests/topotests/isis_lfa_topo1/rt1/bfdd.conf b/tests/topotests/isis_lfa_topo1/rt1/bfdd.conf
new file mode 100644
index 0000000000..86cf68dd8d
--- /dev/null
+++ b/tests/topotests/isis_lfa_topo1/rt1/bfdd.conf
@@ -0,0 +1,6 @@
+hostname rt1
+!
+bfd
+ peer 2001:db8:1000::2 multihop local-address 2001:db8:1000::1
+ !
+!
diff --git a/tests/topotests/isis_lfa_topo1/rt1/step14/show_ipv6_route.ref.diff b/tests/topotests/isis_lfa_topo1/rt1/step14/show_ipv6_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_lfa_topo1/rt1/step14/show_ipv6_route.ref.diff
diff --git a/tests/topotests/isis_lfa_topo1/rt1/step15/show_ipv6_route.ref.diff b/tests/topotests/isis_lfa_topo1/rt1/step15/show_ipv6_route.ref.diff
new file mode 100644
index 0000000000..a00d2d3b62
--- /dev/null
+++ b/tests/topotests/isis_lfa_topo1/rt1/step15/show_ipv6_route.ref.diff
@@ -0,0 +1,50 @@
+--- a/rt1/step14/show_ipv6_route.ref
++++ b/rt1/step15/show_ipv6_route.ref
+@@ -6,22 +6,12 @@
+ "selected":true,
+ "destSelected":true,
+ "distance":115,
+- "metric":20,
++ "metric":25,
+ "installed":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "afi":"ipv6",
+- "interfaceName":"eth-rt2",
+- "active":true,
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "afi":"ipv6",
+ "interfaceName":"eth-rt3",
+ "active":true
+ }
+@@ -151,22 +141,12 @@
+ "selected":true,
+ "destSelected":true,
+ "distance":115,
+- "metric":25,
++ "metric":30,
+ "installed":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "afi":"ipv6",
+- "interfaceName":"eth-rt2",
+- "active":true,
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "afi":"ipv6",
+ "interfaceName":"eth-rt6",
+ "active":true
+ }
diff --git a/tests/topotests/isis_lfa_topo1/rt1/step16/show_ipv6_route.ref.diff b/tests/topotests/isis_lfa_topo1/rt1/step16/show_ipv6_route.ref.diff
new file mode 100644
index 0000000000..5e48511ba5
--- /dev/null
+++ b/tests/topotests/isis_lfa_topo1/rt1/step16/show_ipv6_route.ref.diff
@@ -0,0 +1,53 @@
+--- a/rt1/step15/show_ipv6_route.ref
++++ b/rt1/step16/show_ipv6_route.ref
+@@ -32,16 +32,6 @@
+ "fib":true,
+ "afi":"ipv6",
+ "interfaceName":"eth-rt3",
+- "active":true,
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "afi":"ipv6",
+- "interfaceName":"eth-rt2",
+ "active":true
+ }
+ ]
+@@ -90,16 +80,6 @@
+ "fib":true,
+ "afi":"ipv6",
+ "interfaceName":"eth-rt5",
+- "active":true,
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "afi":"ipv6",
+- "interfaceName":"eth-rt2",
+ "active":true
+ }
+ ]
+@@ -119,16 +99,6 @@
+ "fib":true,
+ "afi":"ipv6",
+ "interfaceName":"eth-rt6",
+- "active":true,
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "afi":"ipv6",
+- "interfaceName":"eth-rt2",
+ "active":true
+ }
+ ]
diff --git a/tests/topotests/isis_lfa_topo1/rt2/bfdd.conf b/tests/topotests/isis_lfa_topo1/rt2/bfdd.conf
new file mode 100644
index 0000000000..40357a4d03
--- /dev/null
+++ b/tests/topotests/isis_lfa_topo1/rt2/bfdd.conf
@@ -0,0 +1,6 @@
+hostname rt2
+!
+bfd
+ peer 2001:db8:1000::1 multihop local-address 2001:db8:1000::2
+ !
+!
diff --git a/tests/topotests/isis_lfa_topo1/test_isis_lfa_topo1.py b/tests/topotests/isis_lfa_topo1/test_isis_lfa_topo1.py
index 7e902213e7..1d6d870a4e 100755
--- a/tests/topotests/isis_lfa_topo1/test_isis_lfa_topo1.py
+++ b/tests/topotests/isis_lfa_topo1/test_isis_lfa_topo1.py
@@ -55,6 +55,7 @@ import os
import sys
import pytest
import json
+import time
import tempfile
from functools import partial
@@ -128,7 +129,7 @@ def build_topo(tgen):
files = ["show_ipv6_route.ref", "show_yang_interface_isis_adjacencies.ref"]
for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6", "rt7"]:
outputs[rname] = {}
- for step in range(1, 13 + 1):
+ for step in range(1, 16 + 1):
outputs[rname][step] = {}
for file in files:
if step == 1:
@@ -174,6 +175,9 @@ def setup_module(mod):
router.load_config(
TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname))
)
+ router.load_config(
+ TopoRouter.RD_BFD, os.path.join(CWD, "/dev/null".format(rname))
+ )
tgen.start_router()
@@ -186,7 +190,7 @@ def teardown_module(mod):
tgen.stop_topology()
-def router_compare_json_output(rname, command, reference):
+def router_compare_json_output(rname, command, reference, wait=0.5, count=120):
"Compare router JSON output"
logger.info('Comparing router "%s" "%s" output', rname, command)
@@ -196,7 +200,7 @@ def router_compare_json_output(rname, command, reference):
# Run test function until we get an result. Wait at most 60 seconds.
test_func = partial(topotest.router_json_cmp, tgen.gears[rname], command, expected)
- _, diff = topotest.run_and_expect(test_func, None, count=120, wait=0.5)
+ _, diff = topotest.run_and_expect(test_func, None, count=count, wait=wait)
assertmsg = '"{}" JSON output mismatches the expected result'.format(rname)
assert diff is None, assertmsg
@@ -616,6 +620,394 @@ def test_rib_ipv6_step13():
)
+#
+# Step 14
+#
+# Action(s):
+# - Setting spf-delay-ietf init-delay of 15s
+#
+# Expected changes:
+# - No routing table change
+# - At the end of test, SPF reacts to a failure in 15s
+#
+def test_rib_ipv6_step14():
+ logger.info("Test (step 14): verify IPv6 RIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("Setting spf-delay-ietf init-delay of 15s")
+ tgen.net["rt1"].cmd(
+ 'vtysh -c "conf t" -c "router isis 1" -c "spf-delay-ietf init-delay 15000 short-delay 0 long-delay 0 holddown 0 time-to-learn 0"'
+ )
+
+ for rname in ["rt1"]:
+ router_compare_json_output(
+ rname,
+ "show ipv6 route isis json",
+ outputs[rname][14]["show_ipv6_route.ref"],
+ )
+
+
+#
+# Step 15
+#
+# Action(s):
+# - shut the eth-rt2 interface on rt1
+#
+# Expected changes:
+# - Route switchover of routes via eth-rt2
+#
+def test_rib_ipv6_step15():
+ logger.info("Test (step 15): verify IPv6 RIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("Shut the interface to rt2 from the switch side and check fast-reroute")
+ tgen.net.cmd_raises("ip link set %s down" % tgen.net["s1"].intfs[0])
+
+ for rname in ["rt1"]:
+ router_compare_json_output(
+ rname,
+ "show ipv6 route isis json",
+ outputs[rname][15]["show_ipv6_route.ref"],
+ count=2,
+ wait=0.05,
+ )
+
+
+#
+# Step 16
+#
+# Action(s): wait for the convergence and SPF computation on rt1
+#
+# Expected changes:
+# - convergence of IPv6 RIB
+#
+def test_rib_ipv6_step16():
+ logger.info("Test (step 16): verify IPv6 RIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("Check SPF convergence")
+
+ for rname in ["rt1"]:
+ router_compare_json_output(
+ rname,
+ "show ipv6 route isis json",
+ outputs[rname][16]["show_ipv6_route.ref"],
+ )
+
+
+#
+# Step 17
+#
+# Action(s):
+# - Setting spf-delay-ietf init-delay of 15s
+#
+# Expected changes:
+# - No routing table change
+# - At the end of test, SPF reacts to a failure in 15s
+#
+def test_rib_ipv6_step17():
+ logger.info("Test (step 17): verify IPv6 RIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info(
+ "Unshut the interface to rt2 from the switch side and check fast-reroute"
+ )
+ tgen.net.cmd_raises("ip link set %s up" % tgen.net["s1"].intfs[0])
+
+ logger.info("Unset link-detect on rt1 eth-rt2")
+ # Unset link detection. We want zebra to consider linkdow as operationaly up
+ # in order that BFD triggers LFA instead of the interface down
+ tgen.net["rt1"].cmd('vtysh -c "conf t" -c "int eth-rt2" -c "no link-detect"')
+
+ for rname in ["rt1"]:
+ router_compare_json_output(
+ rname,
+ "show ipv6 route isis json",
+ outputs[rname][14]["show_ipv6_route.ref"],
+ )
+
+
+#
+# Step 18
+#
+# Action(s):
+# - shut the eth-rt2 interface on rt1
+#
+# Expected changes:
+# - Route switchover of routes via eth-rt2
+#
+def test_rib_ipv6_step18():
+ logger.info("Test (step 18): verify IPv6 RIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("Shut the interface to rt2 from the switch side and check fast-reroute")
+ tgen.net.cmd_raises("ip link set %s down" % tgen.net["s1"].intfs[0])
+
+ rname = "rt1"
+
+ retry = 200 + 1
+
+ while retry:
+ retry -= 1
+ output = tgen.gears[rname].vtysh_cmd("show isis neighbor json")
+ output_json = json.loads(output)
+ found = False
+ for neighbor in output_json["areas"][0]["circuits"]:
+ if "adj" in neighbor and neighbor["adj"] == "rt2":
+ found = True
+ break
+ if not found:
+ break
+ time.sleep(0.05)
+
+ assert not found, "rt2 neighbor is still present"
+
+ router_compare_json_output(
+ rname,
+ "show ipv6 route isis json",
+ outputs[rname][15]["show_ipv6_route.ref"],
+ count=2,
+ wait=0.05,
+ )
+
+
+#
+# Step 19
+#
+# Action(s): wait for the convergence and SPF computation on rt1
+#
+# Expected changes:
+# - convergence of IPv6 RIB
+#
+def test_rib_ipv6_step19():
+ logger.info("Test (step 19): verify IPv6 RIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("Check SPF convergence")
+
+ for rname in ["rt1"]:
+ router_compare_json_output(
+ rname,
+ "show ipv6 route isis json",
+ outputs[rname][16]["show_ipv6_route.ref"],
+ )
+
+
+#
+# Step 20
+#
+# Action(s):
+# - Setting spf-delay-ietf init-delay of 15s
+#
+# Expected changes:
+# - No routing table change
+# - At the end of test, SPF reacts to a failure in 15s
+#
+def test_rib_ipv6_step20():
+ logger.info("Test (step 20): verify IPv6 RIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info(
+ "Unshut the interface to rt2 from the switch side and check fast-reroute"
+ )
+ tgen.net.cmd_raises("ip link set %s up" % tgen.net["s1"].intfs[0])
+
+ for rname in ["rt1"]:
+ router_compare_json_output(
+ rname,
+ "show ipv6 route isis json",
+ outputs[rname][14]["show_ipv6_route.ref"],
+ )
+
+
+#
+# Step 21
+#
+# Action(s):
+# - shut the eth-rt2 interface on rt1
+#
+# Expected changes:
+# - Route switchover of routes via eth-rt2
+#
+def test_rib_ipv6_step21():
+ logger.info("Test (step 21): verify IPv6 RIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ rname = "rt1"
+
+ logger.info("Shut the interface to rt2 from the switch side and check fast-reroute")
+ tgen.gears[rname].vtysh_cmd("clear isis neighbor rt2")
+
+ router_compare_json_output(
+ rname,
+ "show ipv6 route isis json",
+ outputs[rname][15]["show_ipv6_route.ref"],
+ count=2,
+ wait=0.05,
+ )
+
+
+#
+# Step 22
+#
+# Action(s): wait for the convergence and SPF computation on rt1
+#
+# Expected changes:
+# - convergence of IPv6 RIB
+#
+def test_rib_ipv6_step22():
+ logger.info("Test (step 22): verify IPv6 RIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("Check SPF convergence")
+
+ for rname in ["rt1"]:
+ router_compare_json_output(
+ rname,
+ "show ipv6 route isis json",
+ outputs[rname][16]["show_ipv6_route.ref"],
+ )
+
+
+#
+# Step 23
+#
+# Action(s):
+# - Setting spf-delay-ietf init-delay of 15s
+#
+# Expected changes:
+# - No routing table change
+# - At the end of test, SPF reacts to a failure in 15s
+#
+def test_rib_ipv6_step23():
+ logger.info("Test (step 23): verify IPv6 RIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("Setup BFD on rt1 and rt2")
+ for rname in ["rt1", "rt2"]:
+ conf_file = os.path.join(CWD, "{}/bfdd.conf".format(rname))
+ tgen.net[rname].cmd("vtysh -f {}".format(conf_file))
+
+ rname = "rt1"
+ expect = '[{"multihop":true,"peer":"2001:db8:1000::2","local":"2001:db8:1000::1","status":"up"}]'
+ router_compare_json_output(rname, "show bfd peers json", expect)
+
+ logger.info("Set ISIS BFD")
+ tgen.net["rt1"].cmd('vtysh -c "conf t" -c "int eth-rt2" -c "isis bfd"')
+ tgen.net["rt2"].cmd('vtysh -c "conf t" -c "int eth-rt1" -c "isis bfd"')
+
+ router_compare_json_output(
+ rname,
+ "show ipv6 route isis json",
+ outputs[rname][14]["show_ipv6_route.ref"],
+ )
+
+
+#
+# Step 24
+#
+# Action(s):
+# - shut the eth-rt2 interface on rt1
+#
+# Expected changes:
+# - Route switchover of routes via eth-rt2
+#
+def test_rib_ipv6_step24():
+ logger.info("Test (step 24): verify IPv6 RIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("Shut the interface to rt2 from the switch side and check fast-reroute")
+ tgen.net.cmd_raises("ip link set %s down" % tgen.net["s1"].intfs[0])
+
+ rname = "rt1"
+ expect = '[{"multihop":true,"peer":"2001:db8:1000::2","local":"2001:db8:1000::1","status":"down"}]'
+ router_compare_json_output(
+ rname,
+ "show bfd peers json",
+ expect,
+ count=20,
+ wait=0.05,
+ )
+
+ router_compare_json_output(
+ rname,
+ "show ipv6 route isis json",
+ outputs[rname][15]["show_ipv6_route.ref"],
+ count=2,
+ wait=0.05,
+ )
+
+
+#
+# Step 25
+#
+# Action(s): wait for the convergence and SPF computation on rt1
+#
+# Expected changes:
+# - convergence of IPv6 RIB
+#
+def test_rib_ipv6_step25():
+ logger.info("Test (step 25): verify IPv6 RIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("Check SPF convergence")
+
+ for rname in ["rt1"]:
+ router_compare_json_output(
+ rname,
+ "show ipv6 route isis json",
+ outputs[rname][16]["show_ipv6_route.ref"],
+ )
+
+
# Memory leak test template
def test_memory_leak():
"Run the memory leak test and report results."
diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step10/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step10/show_ip_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt1/step10/show_ip_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step10/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step10/show_ipv6_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt1/step10/show_ipv6_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step10/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step10/show_mpls_table.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt1/step10/show_mpls_table.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step11/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step11/show_ip_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt1/step11/show_ip_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step11/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step11/show_ipv6_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt1/step11/show_ipv6_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step11/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step11/show_mpls_table.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt1/step11/show_mpls_table.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step12/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step12/show_ip_route.ref.diff
new file mode 100644
index 0000000000..a8d6e6c65e
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt1/step12/show_ip_route.ref.diff
@@ -0,0 +1,19 @@
+--- a/rt1/step11/show_ip_route.ref
++++ b/rt1/step12/show_ip_route.ref
+@@ -110,16 +110,6 @@
+ "labels":[
+ 16060
+ ]
+- },
+- {
+- "fib":true,
+- "ip":"10.0.1.3",
+- "afi":"ipv4",
+- "interfaceName":"eth-sw1",
+- "active":true,
+- "labels":[
+- 16060
+- ]
+ }
+ ]
+ }
diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step12/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step12/show_ipv6_route.ref.diff
new file mode 100644
index 0000000000..637c59f6ef
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt1/step12/show_ipv6_route.ref.diff
@@ -0,0 +1,18 @@
+--- a/rt1/step11/show_ipv6_route.ref
++++ b/rt1/step12/show_ipv6_route.ref
+@@ -105,15 +105,6 @@
+ "labels":[
+ 16061
+ ]
+- },
+- {
+- "fib":true,
+- "afi":"ipv6",
+- "interfaceName":"eth-sw1",
+- "active":true,
+- "labels":[
+- 16061
+- ]
+ }
+ ]
+ }
diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step12/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step12/show_mpls_table.ref.diff
new file mode 100644
index 0000000000..e110bf48eb
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt1/step12/show_mpls_table.ref.diff
@@ -0,0 +1,28 @@
+--- a/rt1/step11/show_mpls_table.ref
++++ b/rt1/step12/show_mpls_table.ref
+@@ -79,12 +79,6 @@
+ "type":"SR (IS-IS)",
+ "outLabel":16060,
+ "installed":true,
+- "nexthop":"10.0.1.3"
+- },
+- {
+- "type":"SR (IS-IS)",
+- "outLabel":16060,
+- "installed":true,
+ "nexthop":"10.0.1.2"
+ }
+ ]
+@@ -96,12 +90,6 @@
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":16061,
+- "installed":true,
+- "interface":"eth-sw1"
+- },
+- {
+- "type":"SR (IS-IS)",
+- "outLabel":16061,
+ "installed":true,
+ "interface":"eth-sw1"
+ }
diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step10/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step10/show_ip_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt2/step10/show_ip_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step10/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step10/show_ipv6_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt2/step10/show_ipv6_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step10/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step10/show_mpls_table.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt2/step10/show_mpls_table.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step11/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step11/show_ip_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt2/step11/show_ip_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step11/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step11/show_ipv6_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt2/step11/show_ipv6_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step11/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step11/show_mpls_table.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt2/step11/show_mpls_table.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step12/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step12/show_ip_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt2/step12/show_ip_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step12/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step12/show_ipv6_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt2/step12/show_ipv6_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step12/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step12/show_mpls_table.ref.diff
new file mode 100644
index 0000000000..84a36442d3
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt2/step12/show_mpls_table.ref.diff
@@ -0,0 +1,20 @@
+--- a/rt2/step11/show_mpls_table.ref
++++ b/rt2/step12/show_mpls_table.ref
+@@ -199,7 +199,7 @@
+ "backupNexthops":[
+ {
+ "type":"SR (IS-IS)",
+- "outLabel":16060,
++ "outLabel":16500,
+ "nexthop":"10.0.1.3"
+ }
+ ]
+@@ -230,7 +230,7 @@
+ "backupNexthops":[
+ {
+ "type":"SR (IS-IS)",
+- "outLabel":16061,
++ "outLabel":16501,
+ "interface":"eth-sw1"
+ }
+ ]
diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step10/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step10/show_ip_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt3/step10/show_ip_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step10/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step10/show_ipv6_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt3/step10/show_ipv6_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step10/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step10/show_mpls_table.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt3/step10/show_mpls_table.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step11/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step11/show_ip_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt3/step11/show_ip_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step11/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step11/show_ipv6_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt3/step11/show_ipv6_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step11/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step11/show_mpls_table.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt3/step11/show_mpls_table.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step12/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step12/show_ip_route.ref.diff
new file mode 100644
index 0000000000..8695cf848f
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt3/step12/show_ip_route.ref.diff
@@ -0,0 +1,58 @@
+--- a/rt3/step11/show_ip_route.ref
++++ b/rt3/step12/show_ip_route.ref
+@@ -198,44 +198,37 @@
+ "selected":true,
+ "destSelected":true,
+ "distance":115,
+- "metric":30,
++ "metric":40,
+ "installed":true,
+ "nexthops":[
+ {
+ "fib":true,
+- "ip":"10.0.4.5",
++ "ip":"10.0.1.2",
+ "afi":"ipv4",
+- "interfaceName":"eth-rt5-1",
++ "interfaceName":"eth-sw1",
+ "active":true,
+- "backupIndex":[
+- 0
+- ],
+ "labels":[
+- 30060
++ 16060
+ ]
+ },
+ {
+ "fib":true,
+- "ip":"10.0.5.5",
++ "ip":"10.0.4.5",
+ "afi":"ipv4",
+- "interfaceName":"eth-rt5-2",
++ "interfaceName":"eth-rt5-1",
+ "active":true,
+- "backupIndex":[
+- 0
+- ],
+ "labels":[
+ 30060
+ ]
+- }
+- ],
+- "backupNexthops":[
++ },
+ {
+- "ip":"10.0.1.2",
++ "fib":true,
++ "ip":"10.0.5.5",
+ "afi":"ipv4",
+- "interfaceName":"eth-sw1",
++ "interfaceName":"eth-rt5-2",
+ "active":true,
+ "labels":[
+- 16060
++ 30060
+ ]
+ }
+ ]
diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step12/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step12/show_ipv6_route.ref.diff
new file mode 100644
index 0000000000..661d0fe75d
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt3/step12/show_ipv6_route.ref.diff
@@ -0,0 +1,45 @@
+--- a/rt3/step11/show_ipv6_route.ref
++++ b/rt3/step12/show_ipv6_route.ref
+@@ -186,7 +186,7 @@
+ "selected":true,
+ "destSelected":true,
+ "distance":115,
+- "metric":30,
++ "metric":40,
+ "installed":true,
+ "nexthops":[
+ {
+@@ -194,9 +194,6 @@
+ "afi":"ipv6",
+ "interfaceName":"eth-rt5-1",
+ "active":true,
+- "backupIndex":[
+- 0
+- ],
+ "labels":[
+ 30061
+ ]
+@@ -206,23 +203,10 @@
+ "afi":"ipv6",
+ "interfaceName":"eth-rt5-2",
+ "active":true,
+- "backupIndex":[
+- 0
+- ],
+ "labels":[
+ 30061
+ ]
+ }
+- ],
+- "backupNexthops":[
+- {
+- "afi":"ipv6",
+- "interfaceName":"eth-sw1",
+- "active":true,
+- "labels":[
+- 16061
+- ]
+- }
+ ]
+ }
+ ]
diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step12/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step12/show_mpls_table.ref.diff
new file mode 100644
index 0000000000..30941b398b
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt3/step12/show_mpls_table.ref.diff
@@ -0,0 +1,60 @@
+--- a/rt3/step11/show_mpls_table.ref
++++ b/rt3/step12/show_mpls_table.ref
+@@ -165,27 +165,8 @@
+ "nexthops":[
+ {
+ "type":"SR (IS-IS)",
+- "outLabel":30060,
+- "installed":true,
+- "nexthop":"10.0.5.5",
+- "backupIndex":[
+- 0
+- ]
+- },
+- {
+- "type":"SR (IS-IS)",
+- "outLabel":30060,
+- "installed":true,
+- "nexthop":"10.0.4.5",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "type":"SR (IS-IS)",
+ "outLabel":16060,
++ "installed":true,
+ "nexthop":"10.0.1.2"
+ }
+ ]
+@@ -196,27 +177,8 @@
+ "nexthops":[
+ {
+ "type":"SR (IS-IS)",
+- "outLabel":30061,
+- "installed":true,
+- "interface":"eth-rt5-2",
+- "backupIndex":[
+- 0
+- ]
+- },
+- {
+- "type":"SR (IS-IS)",
+- "outLabel":30061,
+- "installed":true,
+- "interface":"eth-rt5-1",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "type":"SR (IS-IS)",
+ "outLabel":16061,
++ "installed":true,
+ "interface":"eth-sw1"
+ }
+ ]
diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step10/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step10/show_ip_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt4/step10/show_ip_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step10/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step10/show_ipv6_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt4/step10/show_ipv6_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step10/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step10/show_mpls_table.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt4/step10/show_mpls_table.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step11/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step11/show_ip_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt4/step11/show_ip_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step11/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step11/show_ipv6_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt4/step11/show_ipv6_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step11/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step11/show_mpls_table.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt4/step11/show_mpls_table.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step12/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step12/show_ip_route.ref.diff
new file mode 100644
index 0000000000..2645c5945b
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt4/step12/show_ip_route.ref.diff
@@ -0,0 +1,144 @@
+--- a/rt4/step11/show_ip_route.ref
++++ b/rt4/step12/show_ip_route.ref
+@@ -160,23 +160,13 @@
+ "interfaceName":"eth-rt5",
+ "active":true,
+ "backupIndex":[
+- 0
++ 0,
++ 1
+ ],
+ "labels":[
+ 3
+ ]
+ }
+- ],
+- "backupNexthops":[
+- {
+- "ip":"10.0.7.6",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt6",
+- "active":true,
+- "labels":[
+- 16500
+- ]
+- }
+ ]
+ }
+ ],
+@@ -196,24 +186,10 @@
+ "afi":"ipv4",
+ "interfaceName":"eth-rt6",
+ "active":true,
+- "backupIndex":[
+- 0
+- ],
+ "labels":[
+ 3
+ ]
+ }
+- ],
+- "backupNexthops":[
+- {
+- "ip":"10.0.6.5",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt5",
+- "active":true,
+- "labels":[
+- 30060
+- ]
+- }
+ ]
+ }
+ ],
+@@ -352,19 +328,12 @@
+ "active":true,
+ "backupIndex":[
+ 0,
+- 1,
+- 2
++ 1
+ ]
+ }
+ ],
+ "backupNexthops":[
+ {
+- "ip":"10.0.7.6",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt6",
+- "active":true
+- },
+- {
+ "ip":"10.0.2.2",
+ "afi":"ipv4",
+ "interfaceName":"eth-rt2-1",
+@@ -397,19 +366,12 @@
+ "active":true,
+ "backupIndex":[
+ 0,
+- 1,
+- 2
++ 1
+ ]
+ }
+ ],
+ "backupNexthops":[
+ {
+- "ip":"10.0.7.6",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt6",
+- "active":true
+- },
+- {
+ "ip":"10.0.2.2",
+ "afi":"ipv4",
+ "interfaceName":"eth-rt2-1",
+@@ -439,14 +401,6 @@
+ 0
+ ]
+ }
+- ],
+- "backupNexthops":[
+- {
+- "ip":"10.0.7.6",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt6",
+- "active":true
+- }
+ ]
+ }
+ ],
+@@ -460,18 +414,7 @@
+ {
+ "ip":"10.0.7.6",
+ "afi":"ipv4",
+- "interfaceName":"eth-rt6",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "ip":"10.0.6.5",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt5",
+- "active":true
++ "interfaceName":"eth-rt6"
+ }
+ ]
+ }
+@@ -492,13 +435,6 @@
+ "afi":"ipv4",
+ "interfaceName":"eth-rt5",
+ "active":true
+- },
+- {
+- "fib":true,
+- "ip":"10.0.7.6",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt6",
+- "active":true
+ }
+ ]
+ }
diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step12/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step12/show_ipv6_route.ref.diff
new file mode 100644
index 0000000000..37e3185ae0
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt4/step12/show_ipv6_route.ref.diff
@@ -0,0 +1,50 @@
+--- a/rt4/step11/show_ipv6_route.ref
++++ b/rt4/step12/show_ipv6_route.ref
+@@ -149,23 +149,10 @@
+ "afi":"ipv6",
+ "interfaceName":"eth-rt5",
+ "active":true,
+- "backupIndex":[
+- 0
+- ],
+ "labels":[
+ 3
+ ]
+ }
+- ],
+- "backupNexthops":[
+- {
+- "afi":"ipv6",
+- "interfaceName":"eth-rt6",
+- "active":true,
+- "labels":[
+- 16501
+- ]
+- }
+ ]
+ }
+ ],
+@@ -184,23 +171,10 @@
+ "afi":"ipv6",
+ "interfaceName":"eth-rt6",
+ "active":true,
+- "backupIndex":[
+- 0
+- ],
+ "labels":[
+ 3
+ ]
+ }
+- ],
+- "backupNexthops":[
+- {
+- "afi":"ipv6",
+- "interfaceName":"eth-rt5",
+- "active":true,
+- "labels":[
+- 30061
+- ]
+- }
+ ]
+ }
+ ]
diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step12/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step12/show_mpls_table.ref.diff
new file mode 100644
index 0000000000..186291adac
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt4/step12/show_mpls_table.ref.diff
@@ -0,0 +1,78 @@
+--- a/rt4/step11/show_mpls_table.ref
++++ b/rt4/step12/show_mpls_table.ref
+@@ -179,17 +179,7 @@
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true,
+- "nexthop":"10.0.7.6",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "type":"SR (IS-IS)",
+- "outLabel":30060,
+- "nexthop":"10.0.6.5"
++ "nexthop":"10.0.7.6"
+ }
+ ]
+ },
+@@ -201,17 +191,7 @@
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true,
+- "interface":"eth-rt6",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "type":"SR (IS-IS)",
+- "outLabel":30061,
+- "interface":"eth-rt5"
++ "interface":"eth-rt6"
+ }
+ ]
+ },
+@@ -223,17 +203,7 @@
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true,
+- "nexthop":"10.0.6.5",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "type":"SR (IS-IS)",
+- "outLabel":16500,
+- "nexthop":"10.0.7.6"
++ "nexthop":"10.0.6.5"
+ }
+ ]
+ },
+@@ -245,17 +215,7 @@
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true,
+- "interface":"eth-rt5",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "type":"SR (IS-IS)",
+- "outLabel":16501,
+- "interface":"eth-rt6"
++ "interface":"eth-rt5"
+ }
+ ]
+ }
diff --git a/tests/topotests/isis_tilfa_topo1/rt5/bfdd.conf b/tests/topotests/isis_tilfa_topo1/rt5/bfdd.conf
new file mode 100644
index 0000000000..d27625ff35
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt5/bfdd.conf
@@ -0,0 +1,14 @@
+hostname rt5
+!
+#debug bfd network
+#debug bfd peer
+#debug bfd zebra
+!
+bfd
+ peer 10.0.8.6 interface eth-rt6
+ detect-multiplier 3
+ receive-interval 300
+ transmit-interval 300
+ no shutdown
+ !
+! \ No newline at end of file
diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ip_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ip_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ipv6_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ipv6_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step10/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_mpls_table.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_mpls_table.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step11/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step11/show_ip_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt5/step11/show_ip_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step11/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step11/show_ipv6_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt5/step11/show_ipv6_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step11/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step11/show_mpls_table.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt5/step11/show_mpls_table.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step12/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step12/show_ip_route.ref.diff
new file mode 100644
index 0000000000..3d21c04297
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt5/step12/show_ip_route.ref.diff
@@ -0,0 +1,151 @@
+--- a/rt5/step11/show_ip_route.ref
++++ b/rt5/step12/show_ip_route.ref
+@@ -159,24 +159,10 @@
+ "afi":"ipv4",
+ "interfaceName":"eth-rt4",
+ "active":true,
+- "backupIndex":[
+- 0
+- ],
+ "labels":[
+ 3
+ ]
+ }
+- ],
+- "backupNexthops":[
+- {
+- "ip":"10.0.8.6",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt6",
+- "active":true,
+- "labels":[
+- 16040
+- ]
+- }
+ ]
+ }
+ ],
+@@ -187,25 +173,11 @@
+ "selected":true,
+ "destSelected":true,
+ "distance":115,
+- "metric":20,
++ "metric":30,
+ "installed":true,
+ "nexthops":[
+ {
+ "fib":true,
+- "ip":"10.0.8.6",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt6",
+- "active":true,
+- "backupIndex":[
+- 0
+- ],
+- "labels":[
+- 3
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+ "ip":"10.0.6.4",
+ "afi":"ipv4",
+ "interfaceName":"eth-rt4",
+@@ -276,19 +248,12 @@
+ "active":true,
+ "backupIndex":[
+ 0,
+- 1,
+- 2
++ 1
+ ]
+ }
+ ],
+ "backupNexthops":[
+ {
+- "ip":"10.0.8.6",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt6",
+- "active":true
+- },
+- {
+ "ip":"10.0.4.3",
+ "afi":"ipv4",
+ "interfaceName":"eth-rt3-1",
+@@ -321,19 +286,12 @@
+ "active":true,
+ "backupIndex":[
+ 0,
+- 1,
+- 2
++ 1
+ ]
+ }
+ ],
+ "backupNexthops":[
+ {
+- "ip":"10.0.8.6",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt6",
+- "active":true
+- },
+- {
+ "ip":"10.0.4.3",
+ "afi":"ipv4",
+ "interfaceName":"eth-rt3-1",
+@@ -439,14 +397,6 @@
+ 0
+ ]
+ }
+- ],
+- "backupNexthops":[
+- {
+- "ip":"10.0.8.6",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt6",
+- "active":true
+- }
+ ]
+ }
+ ],
+@@ -465,39 +415,6 @@
+ "ip":"10.0.6.4",
+ "afi":"ipv4",
+ "interfaceName":"eth-rt4",
+- "active":true
+- },
+- {
+- "fib":true,
+- "ip":"10.0.8.6",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt6",
+- "active":true
+- }
+- ]
+- }
+- ],
+- "10.0.8.0\/24":[
+- {
+- "prefix":"10.0.8.0\/24",
+- "protocol":"isis",
+- "distance":115,
+- "metric":20,
+- "nexthops":[
+- {
+- "ip":"10.0.8.6",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt6",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "ip":"10.0.6.4",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt4",
+ "active":true
+ }
+ ]
diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step12/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step12/show_ipv6_route.ref.diff
new file mode 100644
index 0000000000..66a9dace8b
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt5/step12/show_ipv6_route.ref.diff
@@ -0,0 +1,53 @@
+--- a/rt5/step11/show_ipv6_route.ref
++++ b/rt5/step12/show_ipv6_route.ref
+@@ -149,23 +149,10 @@
+ "afi":"ipv6",
+ "interfaceName":"eth-rt4",
+ "active":true,
+- "backupIndex":[
+- 0
+- ],
+ "labels":[
+ 3
+ ]
+ }
+- ],
+- "backupNexthops":[
+- {
+- "afi":"ipv6",
+- "interfaceName":"eth-rt6",
+- "active":true,
+- "labels":[
+- 16041
+- ]
+- }
+ ]
+ }
+ ],
+@@ -176,25 +163,12 @@
+ "selected":true,
+ "destSelected":true,
+ "distance":115,
+- "metric":20,
++ "metric":30,
+ "installed":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "afi":"ipv6",
+- "interfaceName":"eth-rt6",
+- "active":true,
+- "backupIndex":[
+- 0
+- ],
+- "labels":[
+- 3
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "afi":"ipv6",
+ "interfaceName":"eth-rt4",
+ "active":true,
+ "labels":[
diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step12/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step12/show_mpls_table.ref.diff
new file mode 100644
index 0000000000..cdfc407f93
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt5/step12/show_mpls_table.ref.diff
@@ -0,0 +1,80 @@
+--- a/rt5/step11/show_mpls_table.ref
++++ b/rt5/step12/show_mpls_table.ref
+@@ -179,17 +179,7 @@
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true,
+- "nexthop":"10.0.6.4",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "type":"SR (IS-IS)",
+- "outLabel":16040,
+- "nexthop":"10.0.8.6"
++ "nexthop":"10.0.6.4"
+ }
+ ]
+ },
+@@ -201,17 +191,7 @@
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true,
+- "interface":"eth-rt4",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "type":"SR (IS-IS)",
+- "outLabel":16041,
+- "interface":"eth-rt6"
++ "interface":"eth-rt4"
+ }
+ ]
+ },
+@@ -221,18 +201,8 @@
+ "nexthops":[
+ {
+ "type":"SR (IS-IS)",
+- "outLabel":3,
+- "installed":true,
+- "nexthop":"10.0.8.6",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "type":"SR (IS-IS)",
+ "outLabel":16060,
++ "installed":true,
+ "nexthop":"10.0.6.4"
+ }
+ ]
+@@ -243,18 +213,8 @@
+ "nexthops":[
+ {
+ "type":"SR (IS-IS)",
+- "outLabel":3,
+- "installed":true,
+- "interface":"eth-rt6",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "type":"SR (IS-IS)",
+ "outLabel":16061,
++ "installed":true,
+ "interface":"eth-rt4"
+ }
+ ]
diff --git a/tests/topotests/isis_tilfa_topo1/rt6/bfdd.conf b/tests/topotests/isis_tilfa_topo1/rt6/bfdd.conf
new file mode 100644
index 0000000000..0c8ba7268c
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt6/bfdd.conf
@@ -0,0 +1,14 @@
+hostname rt6
+!
+#debug bfd network
+#debug bfd peer
+#debug bfd zebra
+!
+bfd
+ peer 10.0.8.5 interface eth-rt5
+ detect-multiplier 3
+ receive-interval 300
+ transmit-interval 300
+ no shutdown
+ !
+! \ No newline at end of file
diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step10/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step10/show_ip_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt6/step10/show_ip_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step10/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step10/show_ipv6_route.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt6/step10/show_ipv6_route.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step10/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step10/show_mpls_table.ref.diff
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt6/step10/show_mpls_table.ref.diff
diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step11/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step11/show_ip_route.ref.diff
new file mode 100644
index 0000000000..e477e87d1e
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt6/step11/show_ip_route.ref.diff
@@ -0,0 +1,125 @@
+--- a/rt6/step10/show_ip_route.ref
++++ b/rt6/step11/show_ip_route.ref
+@@ -76,25 +76,11 @@
+ "selected":true,
+ "destSelected":true,
+ "distance":115,
+- "metric":30,
++ "metric":40,
+ "installed":true,
+ "nexthops":[
+ {
+ "fib":true,
+- "ip":"10.0.8.5",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt5",
+- "active":true,
+- "backupIndex":[
+- 0
+- ],
+- "labels":[
+- 30030
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+ "ip":"10.0.7.4",
+ "afi":"ipv4",
+ "interfaceName":"eth-rt4",
+@@ -150,25 +136,11 @@
+ "selected":true,
+ "destSelected":true,
+ "distance":115,
+- "metric":20,
++ "metric":30,
+ "installed":true,
+ "nexthops":[
+ {
+ "fib":true,
+- "ip":"10.0.8.5",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt5",
+- "active":true,
+- "backupIndex":[
+- 0
+- ],
+- "labels":[
+- 3
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+ "ip":"10.0.7.4",
+ "afi":"ipv4",
+ "interfaceName":"eth-rt4",
+@@ -276,22 +248,11 @@
+ "selected":true,
+ "destSelected":true,
+ "distance":115,
+- "metric":20,
++ "metric":30,
+ "installed":true,
+ "nexthops":[
+ {
+ "fib":true,
+- "ip":"10.0.8.5",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt5",
+- "active":true,
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+ "ip":"10.0.7.4",
+ "afi":"ipv4",
+ "interfaceName":"eth-rt4",
+@@ -307,22 +268,11 @@
+ "selected":true,
+ "destSelected":true,
+ "distance":115,
+- "metric":20,
++ "metric":30,
+ "installed":true,
+ "nexthops":[
+ {
+ "fib":true,
+- "ip":"10.0.8.5",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt5",
+- "active":true,
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+ "ip":"10.0.7.4",
+ "afi":"ipv4",
+ "interfaceName":"eth-rt4",
+@@ -389,19 +339,9 @@
+ "prefix":"10.0.8.0\/24",
+ "protocol":"isis",
+ "distance":115,
+- "metric":20,
++ "metric":30,
+ "nexthops":[
+ {
+- "ip":"10.0.8.5",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt5",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+ "ip":"10.0.7.4",
+ "afi":"ipv4",
+ "interfaceName":"eth-rt4",
diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step11/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step11/show_ipv6_route.ref.diff
new file mode 100644
index 0000000000..12e0b591d2
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt6/step11/show_ipv6_route.ref.diff
@@ -0,0 +1,56 @@
+--- a/rt6/step10/show_ipv6_route.ref
++++ b/rt6/step11/show_ipv6_route.ref
+@@ -72,25 +72,12 @@
+ "selected":true,
+ "destSelected":true,
+ "distance":115,
+- "metric":30,
++ "metric":40,
+ "installed":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "afi":"ipv6",
+- "interfaceName":"eth-rt5",
+- "active":true,
+- "backupIndex":[
+- 0
+- ],
+- "labels":[
+- 30031
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "afi":"ipv6",
+ "interfaceName":"eth-rt4",
+ "active":true,
+ "labels":[
+@@ -142,25 +129,12 @@
+ "selected":true,
+ "destSelected":true,
+ "distance":115,
+- "metric":20,
++ "metric":30,
+ "installed":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "afi":"ipv6",
+- "interfaceName":"eth-rt5",
+- "active":true,
+- "backupIndex":[
+- 0
+- ],
+- "labels":[
+- 3
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "afi":"ipv6",
+ "interfaceName":"eth-rt4",
+ "active":true,
+ "labels":[
diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step11/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step11/show_mpls_table.ref.diff
new file mode 100644
index 0000000000..387dcca3fe
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt6/step11/show_mpls_table.ref.diff
@@ -0,0 +1,106 @@
+--- a/rt6/step10/show_mpls_table.ref
++++ b/rt6/step11/show_mpls_table.ref
+@@ -8,12 +8,6 @@
+ "outLabel":16010,
+ "installed":true,
+ "nexthop":"10.0.7.4"
+- },
+- {
+- "type":"SR (IS-IS)",
+- "outLabel":30010,
+- "installed":true,
+- "nexthop":"10.0.8.5"
+ }
+ ]
+ },
+@@ -26,12 +20,6 @@
+ "outLabel":16011,
+ "installed":true,
+ "interface":"eth-rt4"
+- },
+- {
+- "type":"SR (IS-IS)",
+- "outLabel":30011,
+- "installed":true,
+- "interface":"eth-rt5"
+ }
+ ]
+ },
+@@ -85,18 +73,8 @@
+ "nexthops":[
+ {
+ "type":"SR (IS-IS)",
+- "outLabel":30030,
+- "installed":true,
+- "nexthop":"10.0.8.5",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "type":"SR (IS-IS)",
+ "outLabel":16030,
++ "installed":true,
+ "nexthop":"10.0.7.4"
+ }
+ ]
+@@ -107,17 +85,6 @@
+ "nexthops":[
+ {
+ "type":"SR (IS-IS)",
+- "outLabel":30031,
+- "installed":true,
+- "interface":"eth-rt5",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "type":"SR (IS-IS)",
+ "outLabel":16031,
+ "interface":"eth-rt4"
+ }
+@@ -173,18 +140,8 @@
+ "nexthops":[
+ {
+ "type":"SR (IS-IS)",
+- "outLabel":3,
+- "installed":true,
+- "nexthop":"10.0.8.5",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "type":"SR (IS-IS)",
+ "outLabel":16500,
++ "installed":true,
+ "nexthop":"10.0.7.4"
+ }
+ ]
+@@ -195,18 +152,8 @@
+ "nexthops":[
+ {
+ "type":"SR (IS-IS)",
+- "outLabel":3,
+- "installed":true,
+- "interface":"eth-rt5",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "type":"SR (IS-IS)",
+ "outLabel":16501,
++ "installed":true,
+ "interface":"eth-rt4"
+ }
+ ]
diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step12/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step12/show_ip_route.ref.diff
new file mode 100644
index 0000000000..1086b6e706
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt6/step12/show_ip_route.ref.diff
@@ -0,0 +1,153 @@
+--- a/rt6/step12/show_ip_route.ref
++++ b/rt6/step12/show_ip_route.ref
+@@ -18,16 +18,6 @@
+ "labels":[
+ 16010
+ ]
+- },
+- {
+- "fib":true,
+- "ip":"10.0.8.5",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt5",
+- "active":true,
+- "labels":[
+- 30010
+- ]
+ }
+ ]
+ }
+@@ -48,24 +38,10 @@
+ "afi":"ipv4",
+ "interfaceName":"eth-rt4",
+ "active":true,
+- "backupIndex":[
+- 0
+- ],
+ "labels":[
+ 16020
+ ]
+ }
+- ],
+- "backupNexthops":[
+- {
+- "ip":"10.0.8.5",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt5",
+- "active":true,
+- "labels":[
+- 30020
+- ]
+- }
+ ]
+ }
+ ],
+@@ -108,24 +84,10 @@
+ "afi":"ipv4",
+ "interfaceName":"eth-rt4",
+ "active":true,
+- "backupIndex":[
+- 0
+- ],
+ "labels":[
+ 3
+ ]
+ }
+- ],
+- "backupNexthops":[
+- {
+- "ip":"10.0.8.5",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt5",
+- "active":true,
+- "labels":[
+- 30040
+- ]
+- }
+ ]
+ }
+ ],
+@@ -168,13 +130,6 @@
+ "afi":"ipv4",
+ "interfaceName":"eth-rt4",
+ "active":true
+- },
+- {
+- "fib":true,
+- "ip":"10.0.8.5",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt5",
+- "active":true
+ }
+ ]
+ }
+@@ -194,17 +149,6 @@
+ "ip":"10.0.7.4",
+ "afi":"ipv4",
+ "interfaceName":"eth-rt4",
+- "active":true,
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "ip":"10.0.8.5",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt5",
+ "active":true
+ }
+ ]
+@@ -225,17 +169,6 @@
+ "ip":"10.0.7.4",
+ "afi":"ipv4",
+ "interfaceName":"eth-rt4",
+- "active":true,
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "ip":"10.0.8.5",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt5",
+ "active":true
+ }
+ ]
+@@ -297,13 +230,6 @@
+ "afi":"ipv4",
+ "interfaceName":"eth-rt4",
+ "active":true
+- },
+- {
+- "fib":true,
+- "ip":"10.0.8.5",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt5",
+- "active":true
+ }
+ ]
+ }
+@@ -318,18 +244,7 @@
+ {
+ "ip":"10.0.7.4",
+ "afi":"ipv4",
+- "interfaceName":"eth-rt4",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "ip":"10.0.8.5",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt5",
+- "active":true
++ "interfaceName":"eth-rt4"
+ }
+ ]
+ }
diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step12/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step12/show_ipv6_route.ref.diff
new file mode 100644
index 0000000000..571c66fb65
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt6/step12/show_ipv6_route.ref.diff
@@ -0,0 +1,66 @@
+--- a/rt6/step12/show_ipv6_route.ref
++++ b/rt6/step12/show_ipv6_route.ref
+@@ -17,15 +17,6 @@
+ "labels":[
+ 16011
+ ]
+- },
+- {
+- "fib":true,
+- "afi":"ipv6",
+- "interfaceName":"eth-rt5",
+- "active":true,
+- "labels":[
+- 30011
+- ]
+ }
+ ]
+ }
+@@ -45,23 +36,10 @@
+ "afi":"ipv6",
+ "interfaceName":"eth-rt4",
+ "active":true,
+- "backupIndex":[
+- 0
+- ],
+ "labels":[
+ 16021
+ ]
+ }
+- ],
+- "backupNexthops":[
+- {
+- "afi":"ipv6",
+- "interfaceName":"eth-rt5",
+- "active":true,
+- "labels":[
+- 30021
+- ]
+- }
+ ]
+ }
+ ],
+@@ -102,23 +80,10 @@
+ "afi":"ipv6",
+ "interfaceName":"eth-rt4",
+ "active":true,
+- "backupIndex":[
+- 0
+- ],
+ "labels":[
+ 3
+ ]
+ }
+- ],
+- "backupNexthops":[
+- {
+- "afi":"ipv6",
+- "interfaceName":"eth-rt5",
+- "active":true,
+- "labels":[
+- 30041
+- ]
+- }
+ ]
+ }
+ ],
diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step12/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step12/show_mpls_table.ref.diff
new file mode 100644
index 0000000000..18322f18a1
--- /dev/null
+++ b/tests/topotests/isis_tilfa_topo1/rt6/step12/show_mpls_table.ref.diff
@@ -0,0 +1,78 @@
+--- a/rt6/step12/show_mpls_table.ref
++++ b/rt6/step12/show_mpls_table.ref
+@@ -31,17 +31,7 @@
+ "type":"SR (IS-IS)",
+ "outLabel":16020,
+ "installed":true,
+- "nexthop":"10.0.7.4",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "type":"SR (IS-IS)",
+- "outLabel":30020,
+- "nexthop":"10.0.8.5"
++ "nexthop":"10.0.7.4"
+ }
+ ]
+ },
+@@ -53,17 +43,7 @@
+ "type":"SR (IS-IS)",
+ "outLabel":16021,
+ "installed":true,
+- "interface":"eth-rt4",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "type":"SR (IS-IS)",
+- "outLabel":30021,
+- "interface":"eth-rt5"
++ "interface":"eth-rt4"
+ }
+ ]
+ },
+@@ -98,17 +78,7 @@
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true,
+- "nexthop":"10.0.7.4",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "type":"SR (IS-IS)",
+- "outLabel":30040,
+- "nexthop":"10.0.8.5"
++ "nexthop":"10.0.7.4"
+ }
+ ]
+ },
+@@ -120,17 +90,7 @@
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true,
+- "interface":"eth-rt4",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "type":"SR (IS-IS)",
+- "outLabel":30041,
+- "interface":"eth-rt5"
++ "interface":"eth-rt4"
+ }
+ ]
+ }, \ No newline at end of file
diff --git a/tests/topotests/isis_tilfa_topo1/test_isis_tilfa_topo1.py b/tests/topotests/isis_tilfa_topo1/test_isis_tilfa_topo1.py
index 07e91f1a48..3f34a87793 100755
--- a/tests/topotests/isis_tilfa_topo1/test_isis_tilfa_topo1.py
+++ b/tests/topotests/isis_tilfa_topo1/test_isis_tilfa_topo1.py
@@ -144,7 +144,7 @@ def build_topo(tgen):
]
for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
outputs[rname] = {}
- for step in range(1, 9 + 1):
+ for step in range(1, 12 + 1):
outputs[rname][step] = {}
for file in files:
if step == 1:
@@ -188,6 +188,9 @@ def setup_module(mod):
router.load_config(
TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname))
)
+ router.load_config(
+ TopoRouter.RD_BFD, os.path.join(CWD, "/dev/null".format(rname))
+ )
tgen.start_router()
@@ -200,7 +203,7 @@ def teardown_module(mod):
tgen.stop_topology()
-def router_compare_json_output(rname, command, reference):
+def router_compare_json_output(rname, command, reference, count=120, wait=0.5):
"Compare router JSON output"
logger.info('Comparing router "%s" "%s" output', rname, command)
@@ -210,7 +213,7 @@ def router_compare_json_output(rname, command, reference):
# Run test function until we get an result. Wait at most 60 seconds.
test_func = partial(topotest.router_json_cmp, tgen.gears[rname], command, expected)
- _, diff = topotest.run_and_expect(test_func, None, count=120, wait=0.5)
+ _, diff = topotest.run_and_expect(test_func, None, count=count, wait=wait)
assertmsg = '"{}" JSON output mismatches the expected result'.format(rname)
assert diff is None, assertmsg
@@ -740,6 +743,367 @@ def test_mpls_lib_step9():
)
+#
+# Step 10
+#
+# Action(s):
+# - Setting spf-delay-ietf init-delay of 15s
+#
+# Expected changes:
+# - No routing table change
+# - At the end of test, SPF reacts to a failure in 15s
+#
+def test_rib_ipv4_step10():
+ logger.info("Test (step 10): verify IPv4 RIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("Setting spf-delay-ietf init-delay of 15s")
+ tgen.net["rt6"].cmd(
+ 'vtysh -c "conf t" -c "router isis 1" -c "spf-delay-ietf init-delay 15000 short-delay 0 long-delay 0 holddown 0 time-to-learn 0"'
+ )
+
+ for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+ router_compare_json_output(
+ rname, "show ip route isis json", outputs[rname][10]["show_ip_route.ref"]
+ )
+
+
+def test_rib_ipv6_step10():
+ logger.info("Test (step 10): verify IPv6 RIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+ router_compare_json_output(
+ rname,
+ "show ipv6 route isis json",
+ outputs[rname][10]["show_ipv6_route.ref"],
+ )
+
+
+def test_mpls_lib_step10():
+ logger.info("Test (step 10): verify MPLS LIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+ router_compare_json_output(
+ rname, "show mpls table json", outputs[rname][10]["show_mpls_table.ref"]
+ )
+
+
+#
+# Step 11
+#
+# Action(s):
+# - shut the eth-rt5 interface on rt6
+#
+# Expected changes:
+# - Route switchover of routes via eth-rt5
+#
+def test_rt6_step11():
+ logger.info(
+ "Test (step 11): Check IPv4/6 RIB and MPLS table after a LFA switchover"
+ )
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info(
+ "Shut a rt6 interface to rt5 from the switch side and check fast-reroute"
+ )
+ tgen.net.cmd_raises("ip link set %s down" % tgen.net["s8"].intfs[1])
+
+ rname = "rt6"
+ router_compare_json_output(
+ rname,
+ "show ip route isis json",
+ outputs[rname][11]["show_ip_route.ref"],
+ count=1,
+ )
+ router_compare_json_output(
+ rname,
+ "show ipv6 route isis json",
+ outputs[rname][11]["show_ipv6_route.ref"],
+ count=1,
+ )
+ router_compare_json_output(
+ rname,
+ "show mpls table json",
+ outputs[rname][11]["show_mpls_table.ref"],
+ count=1,
+ )
+
+
+#
+# Step 12
+#
+# Action(s): wait for the convergence and SPF computation on rt6
+#
+# Expected changes:
+# - convergence of IPv4/6 RIB and MPLS table
+#
+def test_rib_ipv4_step12():
+ logger.info("Test (step 12): verify IPv4 RIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("Check SPF convergence")
+ for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+ router_compare_json_output(
+ rname,
+ "show ip route isis json",
+ outputs[rname][12]["show_ip_route.ref"],
+ )
+
+
+def test_rib_ipv6_step12():
+ logger.info("Test (step 12): verify IPv6 RIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+ router_compare_json_output(
+ rname,
+ "show ipv6 route isis json",
+ outputs[rname][12]["show_ipv6_route.ref"],
+ )
+
+
+def test_mpls_lib_step12():
+ logger.info("Test (step 12): verify MPLS LIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+ router_compare_json_output(
+ rname,
+ "show mpls table json",
+ outputs[rname][12]["show_mpls_table.ref"],
+ )
+
+
+#
+# Step 13
+#
+# Action(s):
+# - shut / unshut a rt6 interface
+# - Setup BFD
+#
+# Expected changes:
+# - All route tables go back to previous state situation
+# - At the end of test, next SPF is scheduled in approximatively 15s
+#
+def test_rib_ipv4_step13():
+ logger.info("Test (step 13): verify IPv4 RIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("Unsetting spf-delay-ietf init-delay of 15s")
+ tgen.net["rt6"].cmd('vtysh -c "conf t" -c "router isis 1" -c "no spf-delay-ietf"')
+
+ logger.info(
+ "Unshut the rt6 interface to rt5 from the switch side and check fast-reroute"
+ )
+ tgen.net.cmd_raises("ip link set %s up" % tgen.net["s8"].intfs[1])
+
+ logger.info("Setup BFD on rt5 and rt6")
+ for rname in ["rt5", "rt6"]:
+ conf_file = os.path.join(CWD, "{}/bfdd.conf".format(rname))
+ tgen.net[rname].cmd("vtysh -f {}".format(conf_file))
+
+ expect = (
+ '[{"multihop":false,"peer":"10.0.8.5","interface":"eth-rt5","status":"up"}]'
+ )
+ router_compare_json_output("rt6", "show bfd peers json", expect)
+
+ logger.info("Unset link-detect on rt6 eth-rt5")
+ # Unset link detection. We want zebra to consider linkdow as operationaly up
+ # in order that BFD triggers LFA instead of the interface down
+ tgen.net["rt6"].cmd('vtysh -c "conf t" -c "int eth-rt5" -c "no link-detect"')
+
+ # reset spf-interval
+ logger.info("Shut/unshut a rt6 eth-rt5 interface and set spf-interval to 15s")
+ tgen.net["rt6"].cmd(
+ 'vtysh -c "conf t" -c "router isis 1" -c "spf-delay-ietf init-delay 15000 short-delay 0 long-delay 0 holddown 0 time-to-learn 0"'
+ )
+
+ for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+ router_compare_json_output(
+ rname, "show ip route isis json", outputs[rname][10]["show_ip_route.ref"]
+ )
+
+ logger.info("Set ISIS BFD")
+ tgen.net["rt5"].cmd('vtysh -c "conf t" -c "int eth-rt6" -c "isis bfd"')
+ tgen.net["rt6"].cmd('vtysh -c "conf t" -c "int eth-rt5" -c "isis bfd"')
+
+
+def test_rib_ipv6_step13():
+ logger.info("Test (step 13): verify IPv6 RIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+ router_compare_json_output(
+ rname,
+ "show ipv6 route isis json",
+ outputs[rname][10]["show_ipv6_route.ref"],
+ )
+
+
+def test_mpls_lib_step13():
+ logger.info("Test (step 13): verify MPLS LIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+ router_compare_json_output(
+ rname, "show mpls table json", outputs[rname][10]["show_mpls_table.ref"]
+ )
+
+
+#
+# Step 14
+#
+# Action(s):
+# - shut the eth-rt5 interface on rt6
+#
+# Expected changes:
+# - Route switchover of routes via eth-rt5
+#
+def test_rt6_step14():
+ logger.info("Test (step 14): verify IPv4/6 RIB and MPLS table")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info(
+ "Shut a rt6 interface to rt5 from the switch side and check fast-reroute"
+ )
+ tgen.net.cmd_raises("ip link set %s down" % tgen.net["s8"].intfs[1])
+
+ rname = "rt6"
+
+ expect = (
+ '[{"multihop":false,"peer":"10.0.8.5","interface":"eth-rt5","status":"down"}]'
+ )
+ router_compare_json_output(
+ rname,
+ "show bfd peers json",
+ expect,
+ count=20,
+ wait=0.05,
+ )
+
+ router_compare_json_output(
+ rname,
+ "show ip route isis json",
+ outputs[rname][11]["show_ip_route.ref"],
+ count=1,
+ )
+ router_compare_json_output(
+ rname,
+ "show ipv6 route isis json",
+ outputs[rname][11]["show_ipv6_route.ref"],
+ count=1,
+ )
+ router_compare_json_output(
+ rname,
+ "show mpls table json",
+ outputs[rname][11]["show_mpls_table.ref"],
+ count=1,
+ )
+
+
+#
+# Step 15
+#
+# Action(s): wait for the convergence and SPF computation on rt6
+#
+# Expected changes:
+# - convergence of IPv4/6 RIB and MPLS table
+#
+def test_rib_ipv4_step15():
+ logger.info("Test (step 15): verify IPv4 RIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("Check SPF convergence")
+ for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+ router_compare_json_output(
+ rname,
+ "show ip route isis json",
+ outputs[rname][12]["show_ip_route.ref"],
+ )
+
+
+def test_rib_ipv6_step15():
+ logger.info("Test (step 15): verify IPv6 RIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+ router_compare_json_output(
+ rname,
+ "show ipv6 route isis json",
+ outputs[rname][12]["show_ipv6_route.ref"],
+ )
+
+
+def test_mpls_lib_step15():
+ logger.info("Test (step 15): verify MPLS LIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+ router_compare_json_output(
+ rname,
+ "show mpls table json",
+ outputs[rname][12]["show_mpls_table.ref"],
+ )
+
+
# Memory leak test template
def test_memory_leak():
"Run the memory leak test and report results."