forked from Mirror/frr
tests: add remote LFA unit tests
Extend the existing SPF unit testing infrastructure so that it can test RLFA as well. These new unit tests are useful to test the RLFA PQ node computation on several different network topologies in a timely manner. Artificial LDP labels (starting from 50000) are used to activate the computed RLFAs. It's worth mentioning that the computed backup routing tables contain both local LFAs and remote LFAs, as running RLFA separately isn't possible. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This commit is contained in:
parent
16fe8cffa1
commit
c40de29448
|
@ -69,6 +69,24 @@ test_find_adjacency(const struct isis_test_node *tnode, const char *hostname)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
mpls_label_t test_topology_node_ldp_label(const struct isis_topology *topology,
|
||||
struct in_addr router_id)
|
||||
{
|
||||
for (size_t i = 0; topology->nodes[i].hostname[0]; i++) {
|
||||
const struct isis_test_node *tnode = &topology->nodes[i];
|
||||
struct in_addr node_router_id;
|
||||
|
||||
if (!tnode->router_id)
|
||||
continue;
|
||||
|
||||
(void)inet_pton(AF_INET, tnode->router_id, &node_router_id);
|
||||
if (IPV4_ADDR_SAME(&router_id, &node_router_id))
|
||||
return (50000 + (i + 1) * 100);
|
||||
}
|
||||
|
||||
return MPLS_INVALID_LABEL;
|
||||
}
|
||||
|
||||
static struct isis_lsp *lsp_add(struct lspdb_head *lspdb,
|
||||
struct isis_area *area, int level,
|
||||
const uint8_t *sysid, uint8_t pseudonode_id)
|
||||
|
|
|
@ -70,6 +70,9 @@ test_topology_find_node(const struct isis_topology *topology,
|
|||
const char *hostname, uint8_t pseudonode_id);
|
||||
extern const struct isis_topology *
|
||||
test_topology_find(struct isis_topology *test_topologies, uint16_t number);
|
||||
extern mpls_label_t
|
||||
test_topology_node_ldp_label(const struct isis_topology *topology,
|
||||
struct in_addr router_id);
|
||||
extern int test_topology_load(const struct isis_topology *topology,
|
||||
struct isis_area *area,
|
||||
struct lspdb_head lspdb[]);
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "isisd/isisd.h"
|
||||
#include "isisd/isis_dynhn.h"
|
||||
#include "isisd/isis_misc.h"
|
||||
#include "isisd/isis_route.h"
|
||||
#include "isisd/isis_spf.h"
|
||||
#include "isisd/isis_spf_private.h"
|
||||
|
||||
|
@ -40,6 +41,7 @@ enum test_type {
|
|||
TEST_SPF = 1,
|
||||
TEST_REVERSE_SPF,
|
||||
TEST_LFA,
|
||||
TEST_RLFA,
|
||||
TEST_TI_LFA,
|
||||
};
|
||||
|
||||
|
@ -105,6 +107,86 @@ static void test_run_lfa(struct vty *vty, const struct isis_topology *topology,
|
|||
isis_spftree_del(spftree_self);
|
||||
}
|
||||
|
||||
static void test_run_rlfa(struct vty *vty, const struct isis_topology *topology,
|
||||
const struct isis_test_node *root,
|
||||
struct isis_area *area, struct lspdb_head *lspdb,
|
||||
int level, int tree,
|
||||
struct lfa_protected_resource *protected_resource)
|
||||
{
|
||||
struct isis_spftree *spftree_self;
|
||||
struct isis_spftree *spftree_reverse;
|
||||
struct isis_spftree *spftree_pc;
|
||||
struct isis_spf_node *spf_node, *node;
|
||||
struct rlfa *rlfa;
|
||||
uint8_t flags;
|
||||
|
||||
/* Run forward SPF in the root node. */
|
||||
flags = F_SPFTREE_NO_ADJACENCIES;
|
||||
spftree_self = isis_spftree_new(area, lspdb, root->sysid, level, tree,
|
||||
SPF_TYPE_FORWARD, flags);
|
||||
isis_run_spf(spftree_self);
|
||||
|
||||
/* Run reverse SPF in the root node. */
|
||||
spftree_reverse = isis_spf_reverse_run(spftree_self);
|
||||
|
||||
/* Run forward SPF on all adjacent routers. */
|
||||
isis_spf_run_neighbors(spftree_self);
|
||||
|
||||
/* Compute the local LFA repair paths. */
|
||||
isis_lfa_compute(area, NULL, spftree_self, protected_resource);
|
||||
|
||||
/* Compute the remote LFA repair paths. */
|
||||
spftree_pc = isis_rlfa_compute(area, spftree_self, spftree_reverse, 0,
|
||||
protected_resource);
|
||||
|
||||
/* Print the extended P-space and Q-space. */
|
||||
vty_out(vty, "P-space (self):\n");
|
||||
RB_FOREACH (node, isis_spf_nodes, &spftree_pc->lfa.p_space)
|
||||
vty_out(vty, " %s\n", print_sys_hostname(node->sysid));
|
||||
vty_out(vty, "\n");
|
||||
RB_FOREACH (spf_node, isis_spf_nodes, &spftree_self->adj_nodes) {
|
||||
if (RB_EMPTY(isis_spf_nodes, &spf_node->lfa.p_space))
|
||||
continue;
|
||||
vty_out(vty, "P-space (%s):\n",
|
||||
print_sys_hostname(spf_node->sysid));
|
||||
RB_FOREACH (node, isis_spf_nodes, &spf_node->lfa.p_space)
|
||||
vty_out(vty, " %s\n", print_sys_hostname(node->sysid));
|
||||
vty_out(vty, "\n");
|
||||
}
|
||||
vty_out(vty, "Q-space:\n");
|
||||
RB_FOREACH (node, isis_spf_nodes, &spftree_pc->lfa.q_space)
|
||||
vty_out(vty, " %s\n", print_sys_hostname(node->sysid));
|
||||
vty_out(vty, "\n");
|
||||
|
||||
/* Print the post-convergence SPT. */
|
||||
isis_print_spftree(vty, spftree_pc);
|
||||
|
||||
/*
|
||||
* Activate the computed RLFAs (if any) using artificial LDP labels for
|
||||
* the PQ nodes.
|
||||
*/
|
||||
frr_each_safe (rlfa_tree, &spftree_self->lfa.remote.rlfas, rlfa) {
|
||||
struct zapi_rlfa_response response = {};
|
||||
|
||||
response.pq_label = test_topology_node_ldp_label(
|
||||
topology, rlfa->pq_address);
|
||||
assert(response.pq_label != MPLS_INVALID_LABEL);
|
||||
isis_rlfa_activate(spftree_self, rlfa, &response);
|
||||
}
|
||||
|
||||
/* Print the SPT and the corresponding main/backup routing tables. */
|
||||
isis_print_spftree(vty, spftree_self);
|
||||
vty_out(vty, "Main:\n");
|
||||
isis_print_routes(vty, spftree_self, false, false);
|
||||
vty_out(vty, "Backup:\n");
|
||||
isis_print_routes(vty, spftree_self, false, true);
|
||||
|
||||
/* Cleanup everything. */
|
||||
isis_spftree_del(spftree_self);
|
||||
isis_spftree_del(spftree_reverse);
|
||||
isis_spftree_del(spftree_pc);
|
||||
}
|
||||
|
||||
static void test_run_ti_lfa(struct vty *vty,
|
||||
const struct isis_topology *topology,
|
||||
const struct isis_test_node *root,
|
||||
|
@ -242,6 +324,11 @@ static int test_run(struct vty *vty, const struct isis_topology *topology,
|
|||
&area->lspdb[level - 1], level,
|
||||
tree, &protected_resource);
|
||||
break;
|
||||
case TEST_RLFA:
|
||||
test_run_rlfa(vty, topology, root, area,
|
||||
&area->lspdb[level - 1], level,
|
||||
tree, &protected_resource);
|
||||
break;
|
||||
case TEST_TI_LFA:
|
||||
test_run_ti_lfa(vty, topology, root, area,
|
||||
&area->lspdb[level - 1], level,
|
||||
|
@ -266,6 +353,7 @@ DEFUN(test_isis, test_isis_cmd,
|
|||
spf\
|
||||
|reverse-spf\
|
||||
|lfa system-id WORD [pseudonode-id <1-255>]\
|
||||
|remote-lfa system-id WORD [pseudonode-id <1-255>]\
|
||||
|ti-lfa system-id WORD [pseudonode-id <1-255>] [node-protection]\
|
||||
>\
|
||||
[display-lspdb] [<ipv4-only|ipv6-only>] [<level-1-only|level-2-only>]",
|
||||
|
@ -282,6 +370,11 @@ DEFUN(test_isis, test_isis_cmd,
|
|||
"System ID\n"
|
||||
"Pseudonode-ID\n"
|
||||
"Pseudonode-ID\n"
|
||||
"Remote LFA\n"
|
||||
"System ID\n"
|
||||
"System ID\n"
|
||||
"Pseudonode-ID\n"
|
||||
"Pseudonode-ID\n"
|
||||
"Topology Independent LFA\n"
|
||||
"System ID\n"
|
||||
"System ID\n"
|
||||
|
@ -330,6 +423,14 @@ DEFUN(test_isis, test_isis_cmd,
|
|||
else if (argv_find(argv, argc, "lfa", &idx)) {
|
||||
test_type = TEST_LFA;
|
||||
|
||||
fail_sysid_str = argv[idx + 2]->arg;
|
||||
if (argv_find(argv, argc, "pseudonode-id", &idx))
|
||||
fail_pseudonode_id =
|
||||
strtoul(argv[idx + 1]->arg, NULL, 10);
|
||||
protection_type = LFA_LINK_PROTECTION;
|
||||
} else if (argv_find(argv, argc, "remote-lfa", &idx)) {
|
||||
test_type = TEST_RLFA;
|
||||
|
||||
fail_sysid_str = argv[idx + 2]->arg;
|
||||
if (argv_find(argv, argc, "pseudonode-id", &idx))
|
||||
fail_pseudonode_id =
|
||||
|
|
|
@ -31,6 +31,18 @@ test isis topology 14 root rt1 lfa system-id rt1 pseudonode-id 1
|
|||
test isis topology 14 root rt1 lfa system-id rt2
|
||||
test isis topology 14 root rt5 lfa system-id rt4
|
||||
|
||||
test isis topology 1 root rt1 remote-lfa system-id rt2
|
||||
test isis topology 2 root rt5 remote-lfa system-id rt1 pseudonode-id 1
|
||||
test isis topology 3 root rt5 remote-lfa system-id rt4 ipv4-only
|
||||
test isis topology 3 root rt5 remote-lfa system-id rt3 ipv4-only
|
||||
test isis topology 5 root rt1 remote-lfa system-id rt2 ipv4-only
|
||||
test isis topology 6 root rt4 remote-lfa system-id rt3 ipv4-only
|
||||
test isis topology 7 root rt11 remote-lfa system-id rt8 ipv4-only
|
||||
test isis topology 7 root rt6 remote-lfa system-id rt5 ipv4-only
|
||||
test isis topology 8 root rt2 remote-lfa system-id rt5 ipv4-only
|
||||
test isis topology 11 root rt2 remote-lfa system-id rt4
|
||||
test isis topology 13 root rt1 remote-lfa system-id rt3 ipv4-only
|
||||
|
||||
test isis topology 1 root rt1 ti-lfa system-id rt2
|
||||
test isis topology 2 root rt1 ti-lfa system-id rt3
|
||||
test isis topology 2 root rt1 ti-lfa system-id rt1 pseudonode-id 1
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue