tests: add IS-IS classic LFA unit tests

These unit tests check the basic LFA loop-free condition on a
variety of different network topologies. None of the implemented
LFA tie-breakers are tested here.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This commit is contained in:
Renato Westphal 2020-11-20 18:35:37 -03:00
parent fc156c28a5
commit c8a4f33195
4 changed files with 1340 additions and 4 deletions

View File

@ -39,6 +39,7 @@
enum test_type { enum test_type {
TEST_SPF = 1, TEST_SPF = 1,
TEST_REVERSE_SPF, TEST_REVERSE_SPF,
TEST_LFA,
TEST_TI_LFA, TEST_TI_LFA,
}; };
@ -72,6 +73,38 @@ static void test_run_spf(struct vty *vty, const struct isis_topology *topology,
isis_spftree_del(spftree); isis_spftree_del(spftree);
} }
static void test_run_lfa(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;
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 forward SPF on all adjacent routers. */
isis_spf_run_neighbors(spftree_self);
/* Compute the LFA repair paths. */
isis_lfa_compute(area, NULL, spftree_self, protected_resource);
/* 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);
}
static void test_run_ti_lfa(struct vty *vty, static void test_run_ti_lfa(struct vty *vty,
const struct isis_topology *topology, const struct isis_topology *topology,
const struct isis_test_node *root, const struct isis_test_node *root,
@ -120,7 +153,9 @@ static void test_run_ti_lfa(struct vty *vty,
vty_out(vty, " %s\n", print_sys_hostname(node->sysid)); vty_out(vty, " %s\n", print_sys_hostname(node->sysid));
vty_out(vty, "\n"); vty_out(vty, "\n");
/* Print the post-convergence SPT and the correspoding routing table. */ /*
* Print the post-convergence SPT and the corresponding routing table.
*/
isis_print_spftree(vty, spftree_pc); isis_print_spftree(vty, spftree_pc);
isis_print_routes(vty, spftree_self, false, true); isis_print_routes(vty, spftree_self, false, true);
@ -202,6 +237,11 @@ static int test_run(struct vty *vty, const struct isis_topology *topology,
&area->lspdb[level - 1], level, &area->lspdb[level - 1], level,
tree, true); tree, true);
break; break;
case TEST_LFA:
test_run_lfa(vty, topology, root, area,
&area->lspdb[level - 1], level,
tree, &protected_resource);
break;
case TEST_TI_LFA: case TEST_TI_LFA:
test_run_ti_lfa(vty, topology, root, area, test_run_ti_lfa(vty, topology, root, area,
&area->lspdb[level - 1], level, &area->lspdb[level - 1], level,
@ -221,10 +261,11 @@ static int test_run(struct vty *vty, const struct isis_topology *topology,
} }
DEFUN(test_isis, test_isis_cmd, DEFUN(test_isis, test_isis_cmd,
"test isis topology (1-13) root HOSTNAME\ "test isis topology (1-14) root HOSTNAME\
<\ <\
spf\ spf\
|reverse-spf\ |reverse-spf\
|lfa system-id WORD [pseudonode-id <1-255>]\
|ti-lfa system-id WORD [pseudonode-id <1-255>] [node-protection]\ |ti-lfa system-id WORD [pseudonode-id <1-255>] [node-protection]\
>\ >\
[display-lspdb] [<ipv4-only|ipv6-only>] [<level-1-only|level-2-only>]", [display-lspdb] [<ipv4-only|ipv6-only>] [<level-1-only|level-2-only>]",
@ -236,6 +277,11 @@ DEFUN(test_isis, test_isis_cmd,
"SPF root hostname\n" "SPF root hostname\n"
"Normal Shortest Path First\n" "Normal Shortest Path First\n"
"Reverse Shortest Path First\n" "Reverse Shortest Path First\n"
"Classic LFA\n"
"System ID\n"
"System ID\n"
"Pseudonode-ID\n"
"Pseudonode-ID\n"
"Topology Independent LFA\n" "Topology Independent LFA\n"
"System ID\n" "System ID\n"
"System ID\n" "System ID\n"
@ -281,7 +327,15 @@ DEFUN(test_isis, test_isis_cmd,
test_type = TEST_SPF; test_type = TEST_SPF;
else if (argv_find(argv, argc, "reverse-spf", &idx)) else if (argv_find(argv, argc, "reverse-spf", &idx))
test_type = TEST_REVERSE_SPF; test_type = TEST_REVERSE_SPF;
else if (argv_find(argv, argc, "ti-lfa", &idx)) { 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, "ti-lfa", &idx)) {
test_type = TEST_TI_LFA; test_type = TEST_TI_LFA;
fail_sysid_str = argv[idx + 2]->arg; fail_sysid_str = argv[idx + 2]->arg;
@ -404,7 +458,7 @@ int main(int argc, char **argv)
listnode_add(im->isis, isis); listnode_add(im->isis, isis);
SET_FLAG(im->options, F_ISIS_UNIT_TEST); SET_FLAG(im->options, F_ISIS_UNIT_TEST);
debug_spf_events |= DEBUG_SPF_EVENTS; debug_spf_events |= DEBUG_SPF_EVENTS;
debug_tilfa |= DEBUG_TILFA; debug_lfa |= DEBUG_LFA;
debug_events |= DEBUG_EVENTS; debug_events |= DEBUG_EVENTS;
debug_rte_events |= DEBUG_RTE_EVENTS; debug_rte_events |= DEBUG_RTE_EVENTS;

View File

@ -15,6 +15,22 @@ test isis topology 13 root rt1 spf ipv4-only
test isis topology 4 root rt1 reverse-spf ipv4-only test isis topology 4 root rt1 reverse-spf ipv4-only
test isis topology 11 root rt1 reverse-spf test isis topology 11 root rt1 reverse-spf
test isis topology 1 root rt1 lfa system-id rt2
test isis topology 2 root rt4 lfa system-id rt1 pseudonode-id 1
test isis topology 2 root rt4 lfa system-id rt6
test isis topology 3 root rt1 lfa system-id rt2
test isis topology 3 root rt1 lfa system-id rt3
test isis topology 7 root rt1 lfa system-id rt4
test isis topology 7 root rt7 lfa system-id rt8
test isis topology 7 root rt8 lfa system-id rt11
test isis topology 9 root rt3 lfa system-id rt1
test isis topology 10 root rt8 lfa system-id rt5
test isis topology 11 root rt3 lfa system-id rt5
test isis topology 13 root rt4 lfa system-id rt3
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 ti-lfa system-id rt2 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 rt3
test isis topology 2 root rt1 ti-lfa system-id rt1 pseudonode-id 1 test isis topology 2 root rt1 ti-lfa system-id rt1 pseudonode-id 1

File diff suppressed because it is too large Load Diff

View File

@ -531,6 +531,34 @@
* | +---------------------+ | * | +---------------------+ |
* | | | | * | | | |
* +---------+ +---------+ * +---------+ +---------+
* Test topology 14:
* =================
*
* +---------+ +---------+
* | | | |
* | RT1 | | RT2 |
* | +--------------+ |
* | | | |
* +----+----+ +----+----+
* | |
* | |
* | |
* | +----+----+
* | | |
* | | RT3 |
* +-------------------+ |
* | | |
* | +----+----+
* | |
* | |50
* | |
* +----+----+ +----+----+
* | | | |
* | RT4 | | RT5 |
* | +--------------+ |
* | | | |
* +---------+ +---------+
*/ */
struct isis_topology test_topologies[] = { struct isis_topology test_topologies[] = {
@ -3301,6 +3329,158 @@ struct isis_topology test_topologies[] = {
}, },
}, },
}, },
{
.number = 14,
.nodes = {
{
.hostname = "rt1",
.sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
.level = IS_LEVEL_1,
.router_id = "10.0.255.1",
.protocols = {
.ipv4 = true,
.ipv6 = true,
},
.networks = {
"10.0.255.1/32",
"2001:db8::1/128",
},
.adjacencies = {
{
.hostname = "rt1",
.pseudonode_id = 1,
.metric = 10,
},
{
.hostname = "rt2",
.metric = 10,
},
},
},
{
.hostname = "rt2",
.sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
.level = IS_LEVEL_1,
.router_id = "10.0.255.2",
.protocols = {
.ipv4 = true,
.ipv6 = true,
},
.networks = {
"10.0.255.2/32",
"2001:db8::2/128",
},
.adjacencies = {
{
.hostname = "rt1",
.metric = 20,
},
{
.hostname = "rt3",
.metric = 10,
},
},
},
{
.hostname = "rt3",
.sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
.level = IS_LEVEL_1,
.router_id = "10.0.255.3",
.protocols = {
.ipv4 = true,
.ipv6 = true,
},
.networks = {
"10.0.255.3/32",
"2001:db8::3/128",
},
.adjacencies = {
{
.hostname = "rt1",
.pseudonode_id = 1,
.metric = 10,
},
{
.hostname = "rt2",
.metric = 10,
},
{
.hostname = "rt5",
.metric = 50,
},
},
},
{
.hostname = "rt4",
.sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x04},
.level = IS_LEVEL_1,
.router_id = "10.0.255.4",
.protocols = {
.ipv4 = true,
.ipv6 = true,
},
.networks = {
"10.0.255.4/32",
"2001:db8::4/128",
},
.adjacencies = {
{
.hostname = "rt1",
.pseudonode_id = 1,
.metric = 10,
},
{
.hostname = "rt5",
.metric = 10,
},
},
},
{
.hostname = "rt5",
.sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x05},
.level = IS_LEVEL_1,
.router_id = "10.0.255.5",
.protocols = {
.ipv4 = true,
.ipv6 = true,
},
.networks = {
"10.0.255.5/32",
"2001:db8::5/128",
},
.adjacencies = {
{
.hostname = "rt4",
.metric = 10,
},
{
.hostname = "rt3",
.metric = 50,
},
},
},
{
.hostname = "rt1",
.sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
.pseudonode_id = 1,
.level = IS_LEVEL_1,
.adjacencies = {
{
.hostname = "rt1",
.metric = 0,
},
{
.hostname = "rt3",
.metric = 0,
},
{
.hostname = "rt4",
.metric = 0,
},
},
},
},
},
{ {
/* sentinel */ /* sentinel */
}, },