Merge pull request #6999 from opensourcerouting/isisd-modular-spf

isisd: make the SPF code more modular + reverse SPF + unit tests
This commit is contained in:
Donald Sharp 2020-08-27 07:24:18 -04:00 committed by GitHub
commit 4a097aaf88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 5933 additions and 545 deletions

View File

@ -418,8 +418,8 @@ Showing ISIS information
Show topology IS-IS paths to Intermediate Systems, globally, in area
(level-1) or domain (level-2).
.. index:: show ip route isis
.. clicmd:: show ip route isis
.. index:: show isis route [level-1|level-2]
.. clicmd:: show isis route [level-1|level-2]
Show the ISIS routing table, as determined by the most recent SPF
calculation.

View File

@ -221,7 +221,10 @@ struct fabricd *fabricd_new(struct isis_area *area)
rv->area = area;
rv->initial_sync_state = FABRICD_SYNC_PENDING;
rv->spftree = isis_spftree_new(area);
rv->spftree =
isis_spftree_new(area, &area->lspdb[IS_LEVEL_2 - 1],
area->isis->sysid, ISIS_LEVEL2, SPFTREE_IPV4,
SPF_TYPE_FORWARD, F_SPFTREE_HOPCOUNT_METRIC);
rv->neighbors = skiplist_new(0, neighbor_entry_list_cmp,
neighbor_entry_del_void);
rv->neighbors_neighbors = hash_create(neighbor_entry_hash_key,

View File

@ -43,7 +43,6 @@
#include "isisd/isis_dynhn.h"
#include "isisd/isis_pdu.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_spf.h"
#include "isisd/isis_events.h"
#include "isisd/isis_mt.h"
#include "isisd/isis_tlvs.h"
@ -152,9 +151,6 @@ void isis_delete_adj(void *arg)
if (adj->adj_state != ISIS_ADJ_DOWN)
adj->adj_state = ISIS_ADJ_DOWN;
/* remove from SPF trees */
spftree_area_adj_del(adj->circuit->area, adj);
hook_call(isis_adj_state_change_hook, adj);
XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->area_addresses);

View File

@ -49,11 +49,23 @@ void dyn_cache_init(struct isis *isis)
{
if (dyn_cache == NULL)
dyn_cache = list_new();
thread_add_timer(master, dyn_cache_cleanup, isis, 120,
&isis->t_dync_clean);
if (!CHECK_FLAG(im->options, F_ISIS_UNIT_TEST))
thread_add_timer(master, dyn_cache_cleanup, isis, 120,
&isis->t_dync_clean);
return;
}
void dyn_cache_cleanup_all(void)
{
struct listnode *node, *nnode;
struct isis_dynhn *dyn;
for (ALL_LIST_ELEMENTS(dyn_cache, node, nnode, dyn)) {
list_delete_node(dyn_cache, node);
XFREE(MTYPE_ISIS_DYNHN, dyn);
}
}
static int dyn_cache_cleanup(struct thread *thread)
{
struct listnode *node, *nnode;

View File

@ -31,6 +31,7 @@ struct isis_dynhn {
};
void dyn_cache_init(struct isis *isis);
void dyn_cache_cleanup_all(void);
void isis_dynhn_insert(const uint8_t *id, const char *hostname, int level);
void isis_dynhn_remove(const uint8_t *id);
struct isis_dynhn *dynhn_find_by_id(const uint8_t *id);

View File

@ -2046,6 +2046,160 @@ static int lsp_handle_adj_state_change(struct isis_adjacency *adj)
return 0;
}
/*
* Iterate over all IP reachability TLVs in a LSP (all fragments) of the given
* address-family and MT-ID.
*/
int isis_lsp_iterate_ip_reach(struct isis_lsp *lsp, int family, uint16_t mtid,
lsp_ip_reach_iter_cb cb, void *arg)
{
bool pseudo_lsp = LSP_PSEUDO_ID(lsp->hdr.lsp_id);
struct isis_lsp *frag;
struct listnode *node;
if (lsp->hdr.seqno == 0 || lsp->hdr.rem_lifetime == 0)
return LSP_ITER_CONTINUE;
/* Parse main LSP. */
if (lsp->tlvs) {
if (!fabricd && !pseudo_lsp && family == AF_INET
&& mtid == ISIS_MT_IPV4_UNICAST) {
struct isis_item_list *reachs[] = {
&lsp->tlvs->oldstyle_ip_reach,
&lsp->tlvs->oldstyle_ip_reach_ext};
for (unsigned int i = 0; i < array_size(reachs); i++) {
struct isis_oldstyle_ip_reach *r;
for (r = (struct isis_oldstyle_ip_reach *)
reachs[i]
->head;
r; r = r->next) {
bool external = i ? true : false;
if ((*cb)((struct prefix *)&r->prefix,
r->metric, external, NULL,
arg)
== LSP_ITER_STOP)
return LSP_ITER_STOP;
}
}
}
if (!pseudo_lsp && family == AF_INET) {
struct isis_item_list *ipv4_reachs;
if (mtid == ISIS_MT_IPV4_UNICAST)
ipv4_reachs = &lsp->tlvs->extended_ip_reach;
else
ipv4_reachs = isis_lookup_mt_items(
&lsp->tlvs->mt_ip_reach, mtid);
struct isis_extended_ip_reach *r;
for (r = ipv4_reachs ? (struct isis_extended_ip_reach *)
ipv4_reachs->head
: NULL;
r; r = r->next) {
if ((*cb)((struct prefix *)&r->prefix,
r->metric, false, r->subtlvs, arg)
== LSP_ITER_STOP)
return LSP_ITER_STOP;
}
}
if (!pseudo_lsp && family == AF_INET6) {
struct isis_item_list *ipv6_reachs;
struct isis_ipv6_reach *r;
if (mtid == ISIS_MT_IPV4_UNICAST)
ipv6_reachs = &lsp->tlvs->ipv6_reach;
else
ipv6_reachs = isis_lookup_mt_items(
&lsp->tlvs->mt_ipv6_reach, mtid);
for (r = ipv6_reachs ? (struct isis_ipv6_reach *)
ipv6_reachs->head
: NULL;
r; r = r->next) {
if ((*cb)((struct prefix *)&r->prefix,
r->metric, r->external, r->subtlvs,
arg)
== LSP_ITER_STOP)
return LSP_ITER_STOP;
}
}
}
/* Parse LSP fragments. */
for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) {
if (!frag->tlvs)
continue;
isis_lsp_iterate_ip_reach(frag, family, mtid, cb, arg);
}
return LSP_ITER_CONTINUE;
}
/*
* Iterate over all IS reachability TLVs in a LSP (all fragments) of the given
* MT-ID.
*/
int isis_lsp_iterate_is_reach(struct isis_lsp *lsp, uint16_t mtid,
lsp_is_reach_iter_cb cb, void *arg)
{
bool pseudo_lsp = LSP_PSEUDO_ID(lsp->hdr.lsp_id);
struct isis_lsp *frag;
struct listnode *node;
struct isis_item *head;
struct isis_item_list *te_neighs;
if (lsp->hdr.seqno == 0 || lsp->hdr.rem_lifetime == 0)
return LSP_ITER_CONTINUE;
/* Parse main LSP. */
if (lsp->tlvs) {
if (pseudo_lsp || mtid == ISIS_MT_IPV4_UNICAST) {
head = lsp->tlvs->oldstyle_reach.head;
for (struct isis_oldstyle_reach *reach =
(struct isis_oldstyle_reach *)head;
reach; reach = reach->next) {
if ((*cb)(reach->id, reach->metric, true, NULL,
arg)
== LSP_ITER_STOP)
return LSP_ITER_STOP;
}
}
if (pseudo_lsp || mtid == ISIS_MT_IPV4_UNICAST)
te_neighs = &lsp->tlvs->extended_reach;
else
te_neighs =
isis_get_mt_items(&lsp->tlvs->mt_reach, mtid);
if (te_neighs) {
head = te_neighs->head;
for (struct isis_extended_reach *reach =
(struct isis_extended_reach *)head;
reach; reach = reach->next) {
if ((*cb)(reach->id, reach->metric, false,
reach->subtlvs, arg)
== LSP_ITER_STOP)
return LSP_ITER_STOP;
}
}
}
/* Parse LSP fragments. */
for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) {
if (!frag->tlvs)
continue;
isis_lsp_iterate_is_reach(frag, mtid, cb, arg);
}
return LSP_ITER_CONTINUE;
}
void lsp_init(void)
{
hook_register(isis_adj_state_change_hook,

View File

@ -127,6 +127,26 @@ int lsp_print_all(struct vty *vty, struct lspdb_head *head, char detail,
/* sets SRMflags for all active circuits of an lsp */
void lsp_set_all_srmflags(struct isis_lsp *lsp, bool set);
#define LSP_ITER_CONTINUE 0
#define LSP_ITER_STOP -1
/* Callback used by isis_lsp_iterate_ip_reach() function. */
struct isis_subtlvs;
typedef int (*lsp_ip_reach_iter_cb)(const struct prefix *prefix,
uint32_t metric, bool external,
struct isis_subtlvs *subtlvs, void *arg);
/* Callback used by isis_lsp_iterate_is_reach() function. */
typedef int (*lsp_is_reach_iter_cb)(const uint8_t *id, uint32_t metric,
bool oldmetric,
struct isis_ext_subtlvs *subtlvs,
void *arg);
int isis_lsp_iterate_ip_reach(struct isis_lsp *lsp, int family, uint16_t mtid,
lsp_ip_reach_iter_cb cb, void *arg);
int isis_lsp_iterate_is_reach(struct isis_lsp *lsp, uint16_t mtid,
lsp_is_reach_iter_cb cb, void *arg);
#define lsp_flood(lsp, circuit) \
_lsp_flood((lsp), (circuit), __func__, __FILE__, __LINE__)
void _lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit,

View File

@ -252,7 +252,7 @@ int main(int argc, char **argv, char **envp)
#ifndef FABRICD
isis_cli_init();
#endif /* ifdef FABRICD */
isis_spf_cmds_init();
isis_spf_init();
isis_redist_init();
isis_route_map_init();
isis_mpls_te_init();

View File

@ -437,7 +437,7 @@ struct in_addr newprefix2inaddr(uint8_t *prefix_start, uint8_t prefix_masklen)
* Returns the dynamic hostname associated with the passed system ID.
* If no dynamic hostname found then returns formatted system ID.
*/
const char *print_sys_hostname(uint8_t *sysid)
const char *print_sys_hostname(const uint8_t *sysid)
{
struct isis_dynhn *dyn;
struct isis *isis = NULL;
@ -447,8 +447,7 @@ const char *print_sys_hostname(uint8_t *sysid)
/* For our system ID return our host name */
isis = isis_lookup_by_sysid(sysid);
if (isis != NULL)
if (isis && !CHECK_FLAG(im->options, F_ISIS_UNIT_TEST))
return cmd_hostname_get();
dyn = dynhn_find_by_id(sysid);

View File

@ -49,7 +49,7 @@ const char *time2string(uint32_t);
const char *nlpid2str(uint8_t nlpid);
/* typedef struct nlpids nlpids; */
char *nlpid2string(struct nlpids *);
const char *print_sys_hostname(uint8_t *sysid);
const char *print_sys_hostname(const uint8_t *sysid);
void zlog_dump_data(void *data, int len);
/*

View File

@ -46,6 +46,7 @@
#include "isis_pdu.h"
#include "isis_lsp.h"
#include "isis_spf.h"
#include "isis_spf_private.h"
#include "isis_route.h"
#include "isis_zebra.h"
@ -158,6 +159,17 @@ static void adjinfo2nexthop(int family, struct list *nexthops,
}
}
static void isis_route_add_dummy_nexthops(struct isis_route_info *rinfo,
const uint8_t *sysid)
{
struct isis_nexthop *nh;
nh = XCALLOC(MTYPE_ISIS_NEXTHOP, sizeof(struct isis_nexthop));
memcpy(nh->sysid, sysid, sizeof(nh->sysid));
isis_sr_nexthop_reset(&nh->sr);
listnode_add(rinfo->nexthops, nh);
}
static struct isis_route_info *isis_route_info_new(struct prefix *prefix,
struct prefix_ipv6 *src_p,
uint32_t cost,
@ -165,13 +177,25 @@ static struct isis_route_info *isis_route_info_new(struct prefix *prefix,
struct list *adjacencies)
{
struct isis_route_info *rinfo;
struct isis_adjacency *adj;
struct isis_vertex_adj *vadj;
struct listnode *node;
rinfo = XCALLOC(MTYPE_ISIS_ROUTE_INFO, sizeof(struct isis_route_info));
rinfo->nexthops = list_new();
for (ALL_LIST_ELEMENTS_RO(adjacencies, node, adj)) {
for (ALL_LIST_ELEMENTS_RO(adjacencies, node, vadj)) {
struct isis_spf_adj *sadj = vadj->sadj;
struct isis_adjacency *adj = sadj->adj;
/*
* Create dummy nexthops when running SPF on a testing
* environment.
*/
if (CHECK_FLAG(im->options, F_ISIS_UNIT_TEST)) {
isis_route_add_dummy_nexthops(rinfo, sadj->id);
continue;
}
/* check for force resync this route */
if (CHECK_FLAG(adj->circuit->flags,
ISIS_CIRCUIT_FLAPPED_AFTER_SPF))

File diff suppressed because it is too large Load Diff

View File

@ -26,21 +26,46 @@
struct isis_spftree;
struct isis_spftree *isis_spftree_new(struct isis_area *area);
enum spf_type {
SPF_TYPE_FORWARD = 1,
SPF_TYPE_REVERSE,
};
struct isis_spf_adj {
uint8_t id[ISIS_SYS_ID_LEN + 1];
struct isis_adjacency *adj;
uint32_t metric;
struct isis_ext_subtlvs *subtlvs;
struct {
uint8_t desig_is_id[ISIS_SYS_ID_LEN + 1];
struct isis_lsp *lsp_pseudo;
} lan;
uint8_t flags;
#define F_ISIS_SPF_ADJ_BROADCAST 0x01
#define F_ISIS_SPF_ADJ_OLDMETRIC 0x02
};
struct isis_spftree *isis_spftree_new(struct isis_area *area,
struct lspdb_head *lspdb,
const uint8_t *sysid, int level,
enum spf_tree_id tree_id,
enum spf_type type, uint8_t flags);
void isis_spf_invalidate_routes(struct isis_spftree *tree);
void isis_spf_verify_routes(struct isis_area *area,
struct isis_spftree **trees);
void isis_spftree_del(struct isis_spftree *spftree);
void spftree_area_init(struct isis_area *area);
void spftree_area_del(struct isis_area *area);
void spftree_area_adj_del(struct isis_area *area, struct isis_adjacency *adj);
#define isis_spf_schedule(area, level) \
_isis_spf_schedule((area), (level), __func__, \
__FILE__, __LINE__)
int _isis_spf_schedule(struct isis_area *area, int level,
const char *func, const char *file, int line);
void isis_spf_cmds_init(void);
void isis_print_spftree(struct vty *vty, struct isis_spftree *spftree);
void isis_print_routes(struct vty *vty, struct isis_spftree *spftree);
void isis_spf_init(void);
void isis_spf_print(struct isis_spftree *spftree, struct vty *vty);
void isis_run_spf(struct isis_spftree *spftree);
struct isis_spftree *isis_run_hopcount_spf(struct isis_area *area,
uint8_t *sysid,
struct isis_spftree *spftree);

View File

@ -50,6 +50,11 @@ struct prefix_pair {
struct prefix_ipv6 src;
};
struct isis_vertex_adj {
struct isis_spf_adj *sadj;
struct mpls_label_stack *label_stack;
};
/*
* Triple <N, d(N), {Adj(N)}>
*/
@ -180,6 +185,10 @@ static void isis_vertex_del(struct isis_vertex *vertex)
XFREE(MTYPE_ISIS_VERTEX, vertex);
}
bool isis_vertex_adj_exists(const struct isis_spftree *spftree,
const struct isis_vertex *vertex,
const struct isis_spf_adj *sadj);
__attribute__((__unused__))
static void isis_vertex_queue_clear(struct isis_vertex_queue *queue)
{
@ -297,18 +306,26 @@ struct isis_spftree {
struct isis_vertex_queue paths; /* the SPT */
struct isis_vertex_queue tents; /* TENT */
struct route_table *route_table;
struct lspdb_head *lspdb; /* link-state db */
struct list *sadj_list;
struct isis_area *area; /* back pointer to area */
unsigned int runcount; /* number of runs since uptime */
time_t last_run_timestamp; /* last run timestamp as wall time for display */
time_t last_run_monotime; /* last run as monotime for scheduling */
time_t last_run_duration; /* last run duration in msec */
enum spf_type type;
uint8_t sysid[ISIS_SYS_ID_LEN];
uint16_t mtid;
int family;
int level;
enum spf_tree_id tree_id;
bool hopcount_metric;
uint8_t flags;
};
#define F_SPFTREE_HOPCOUNT_METRIC 0x01
#define F_SPFTREE_NO_ROUTES 0x02
#define F_SPFTREE_NO_ADJACENCIES 0x04
__attribute__((__unused__))
static void isis_vertex_id_init(struct isis_vertex *vertex, const void *id,
@ -347,8 +364,7 @@ static struct isis_lsp *lsp_for_vertex(struct isis_spftree *spftree,
memcpy(lsp_id, vertex->N.id, ISIS_SYS_ID_LEN + 1);
LSP_FRAGMENT(lsp_id) = 0;
struct lspdb_head *lspdb = &spftree->area->lspdb[spftree->level - 1];
struct isis_lsp *lsp = lsp_search(lspdb, lsp_id);
struct isis_lsp *lsp = lsp_search(spftree->lspdb, lsp_id);
if (lsp && lsp->hdr.rem_lifetime != 0)
return lsp;

View File

@ -210,7 +210,7 @@ int isis_sr_cfg_srlb_update(struct isis_area *area, uint32_t lower_bound,
uint32_t upper_bound)
{
struct isis_sr_db *srdb = &area->srdb;
struct listnode *node, *nnode;
struct listnode *node;
struct sr_adjacency *sra;
sr_debug("ISIS-Sr (%s): Update SRLB with new range [%u/%u]",
@ -236,7 +236,7 @@ int isis_sr_cfg_srlb_update(struct isis_area *area, uint32_t lower_bound,
return -1;
/* Reinstall local Adjacency-SIDs with new labels. */
for (ALL_LIST_ELEMENTS(area->srdb.adj_sids, node, nnode, sra))
for (ALL_LIST_ELEMENTS_RO(area->srdb.adj_sids, node, sra))
sr_adj_sid_update(sra, &srdb->srlb);
/* Update and Flood LSP */
@ -1521,13 +1521,13 @@ static void sr_adj_sid_add_single(struct isis_adjacency *adj, int family,
/* Determine nexthop IP address */
switch (family) {
case AF_INET:
if (!circuit->ip_router)
if (!circuit->ip_router || !adj->ipv4_address_count)
return;
nexthop.ipv4 = adj->ipv4_addresses[0];
break;
case AF_INET6:
if (!circuit->ipv6_router)
if (!circuit->ipv6_router || !adj->ipv6_address_count)
return;
nexthop.ipv6 = adj->ipv6_addresses[0];
@ -1986,7 +1986,7 @@ DEFUN(show_sr_prefix_sids, show_sr_prefix_sids_cmd,
"Segment-Routing\n"
"Segment-Routing Prefix-SIDs\n")
{
struct listnode *node, *inode, *nnode;
struct listnode *node, *inode;
struct isis_area *area;
struct isis *isis = NULL;
const char *vrf_name = VRF_DEFAULT_NAME;
@ -1996,7 +1996,7 @@ DEFUN(show_sr_prefix_sids, show_sr_prefix_sids_cmd,
ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
if (vrf_name) {
if (all_vrf) {
for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) {
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node,
area)) {
vty_out(vty, "Area %s:\n",
@ -2084,11 +2084,11 @@ DEFUN(show_sr_node, show_sr_node_cmd,
"Segment-Routing\n"
"Segment-Routing node\n")
{
struct listnode *node, *inode, *nnode;
struct listnode *node, *inode;
struct isis_area *area;
struct isis *isis = NULL;
struct isis *isis;
for (ALL_LIST_ELEMENTS(im->isis, inode, nnode, isis)) {
for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) {
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
vty_out(vty, "Area %s:\n",
area->area_tag ? area->area_tag : "null");

View File

@ -311,7 +311,7 @@ DEFUN(show_isis_mpls_te_router,
MPLS_TE_STR "Router information\n")
{
struct listnode *anode, *nnode, *inode;
struct listnode *anode, *inode;
struct isis_area *area;
struct isis *isis = NULL;
const char *vrf_name = VRF_DEFAULT_NAME;
@ -325,7 +325,7 @@ DEFUN(show_isis_mpls_te_router,
ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
if (vrf_name) {
if (all_vrf) {
for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) {
for (ALL_LIST_ELEMENTS_RO(isis->area_list,
anode, area)) {
if (!IS_MPLS_TE(area->mta))
@ -483,7 +483,7 @@ DEFUN (show_isis_mpls_te_interface,
"Interface information\n"
"Interface name\n")
{
struct listnode *anode, *cnode, *nnode, *inode;
struct listnode *anode, *cnode, *inode;
struct isis_area *area;
struct isis_circuit *circuit;
struct interface *ifp;
@ -497,7 +497,7 @@ DEFUN (show_isis_mpls_te_interface,
if (argc == idx_interface) {
/* Show All Interfaces. */
for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) {
for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode,
area)) {

View File

@ -125,33 +125,37 @@ void isis_vrf_unlink(struct isis *isis, struct vrf *vrf)
struct isis *isis_lookup_by_vrfid(vrf_id_t vrf_id)
{
struct isis *isis = NULL;
struct listnode *node, *nnode;
struct isis *isis;
struct listnode *node;
for (ALL_LIST_ELEMENTS(im->isis, node, nnode, isis))
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
if (isis->vrf_id == vrf_id)
return isis;
return NULL;
}
struct isis *isis_lookup_by_vrfname(const char *vrfname)
{
struct isis *isis = NULL;
struct listnode *node, *nnode;
struct isis *isis;
struct listnode *node;
for (ALL_LIST_ELEMENTS(im->isis, node, nnode, isis))
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
if (isis->name && vrfname && strcmp(isis->name, vrfname) == 0)
return isis;
return NULL;
}
struct isis *isis_lookup_by_sysid(uint8_t *sysid)
struct isis *isis_lookup_by_sysid(const uint8_t *sysid)
{
struct isis *isis = NULL;
struct listnode *node, *nnode;
for (ALL_LIST_ELEMENTS(im->isis, node, nnode, isis))
struct isis *isis;
struct listnode *node;
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
if (!memcmp(isis->sysid, sysid, ISIS_SYS_ID_LEN))
return isis;
return NULL;
}
@ -165,7 +169,7 @@ void isis_master_init(struct thread_master *master)
void isis_global_instance_create()
{
struct isis *isis = NULL;
struct isis *isis;
isis = isis_lookup_by_vrfid(VRF_DEFAULT);
if (isis == NULL) {
@ -176,8 +180,8 @@ void isis_global_instance_create()
struct isis *isis_new(vrf_id_t vrf_id)
{
struct vrf *vrf = NULL;
struct isis *isis = NULL;
struct vrf *vrf;
struct isis *isis;
isis = XCALLOC(MTYPE_ISIS, sizeof(struct isis));
isis->vrf_id = vrf_id;
@ -214,6 +218,27 @@ struct isis_area *isis_area_create(const char *area_tag, const char *vrf_name)
struct vrf *vrf = NULL;
area = XCALLOC(MTYPE_ISIS_AREA, sizeof(struct isis_area));
if (vrf_name) {
vrf = vrf_lookup_by_name(vrf_name);
if (vrf) {
isis = isis_lookup_by_vrfid(vrf->vrf_id);
if (isis == NULL) {
isis = isis_new(vrf->vrf_id);
isis_add(isis);
}
} else
return NULL;
} else {
isis = isis_lookup_by_vrfid(VRF_DEFAULT);
if (isis == NULL) {
isis = isis_new(VRF_DEFAULT);
isis_add(isis);
}
}
listnode_add(isis->area_list, area);
area->isis = isis;
/*
* Fabricd runs only as level-2.
* For IS-IS, the default is level-1-2
@ -237,7 +262,8 @@ struct isis_area *isis_area_create(const char *area_tag, const char *vrf_name)
area->circuit_list = list_new();
area->adjacency_list = list_new();
area->area_addrs = list_new();
thread_add_timer(master, lsp_tick, area, 1, &area->t_tick);
if (!CHECK_FLAG(im->options, F_ISIS_UNIT_TEST))
thread_add_timer(master, lsp_tick, area, 1, &area->t_tick);
flags_initialize(&area->flags);
isis_sr_area_init(area);
@ -293,27 +319,6 @@ struct isis_area *isis_area_create(const char *area_tag, const char *vrf_name)
area->area_tag = strdup(area_tag);
if (vrf_name) {
vrf = vrf_lookup_by_name(vrf_name);
if (vrf) {
isis = isis_lookup_by_vrfid(vrf->vrf_id);
if (isis == NULL) {
isis = isis_new(vrf->vrf_id);
isis_add(isis);
}
} else
return NULL;
} else {
isis = isis_lookup_by_vrfid(VRF_DEFAULT);
if (isis == NULL) {
isis = isis_new(VRF_DEFAULT);
isis_add(isis);
}
}
listnode_add(isis->area_list, area);
area->isis = isis;
if (fabricd)
area->fabricd = fabricd_new(area);
@ -335,7 +340,7 @@ struct isis_area *isis_area_lookup(const char *area_tag, vrf_id_t vrf_id)
{
struct isis_area *area;
struct listnode *node;
struct isis *isis = NULL;
struct isis *isis;
isis = isis_lookup_by_vrfid(vrf_id);
if (isis == NULL)
@ -414,7 +419,8 @@ void isis_area_destroy(struct isis_area *area)
spf_backoff_free(area->spf_delay_ietf[0]);
spf_backoff_free(area->spf_delay_ietf[1]);
isis_redist_area_finish(area);
if (!CHECK_FLAG(im->options, F_ISIS_UNIT_TEST))
isis_redist_area_finish(area);
for (ALL_LIST_ELEMENTS(area->area_addrs, node, nnode, addr)) {
list_delete_node(area->area_addrs, node);
@ -464,7 +470,7 @@ void isis_finish(struct isis *isis)
void isis_terminate()
{
struct isis *isis = NULL;
struct isis *isis;
struct listnode *node, *nnode;
if (listcount(im->isis) == 0)
@ -643,10 +649,10 @@ int area_clear_net_title(struct vty *vty, const char *net_title)
int show_isis_interface_common(struct vty *vty, const char *ifname, char detail,
const char *vrf_name, bool all_vrf)
{
struct listnode *anode, *cnode, *mnode, *inode;
struct listnode *anode, *cnode, *inode;
struct isis_area *area;
struct isis_circuit *circuit;
struct isis *isis = NULL;
struct isis *isis;
if (!im) {
vty_out(vty, "IS-IS Routing Process not enabled\n");
@ -654,7 +660,7 @@ int show_isis_interface_common(struct vty *vty, const char *ifname, char detail,
}
if (vrf_name) {
if (all_vrf) {
for (ALL_LIST_ELEMENTS(im->isis, mnode, inode, isis)) {
for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) {
for (ALL_LIST_ELEMENTS_RO(isis->area_list,
anode, area)) {
vty_out(vty, "Area %s:\n",
@ -677,7 +683,7 @@ int show_isis_interface_common(struct vty *vty, const char *ifname, char detail,
detail);
}
}
return 0;
return CMD_SUCCESS;
}
isis = isis_lookup_by_vrfname(vrf_name);
if (isis != NULL) {
@ -822,10 +828,10 @@ static void isis_neighbor_common(struct vty *vty, const char *id, char detail,
int show_isis_neighbor_common(struct vty *vty, const char *id, char detail,
const char *vrf_name, bool all_vrf)
{
struct listnode *nnode, *inode;
struct listnode *node;
struct isis_dynhn *dynhn;
uint8_t sysid[ISIS_SYS_ID_LEN];
struct isis *isis = NULL;
struct isis *isis;
if (!im) {
vty_out(vty, "IS-IS Routing Process not enabled\n");
@ -846,11 +852,11 @@ int show_isis_neighbor_common(struct vty *vty, const char *id, char detail,
if (vrf_name) {
if (all_vrf) {
for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) {
isis_neighbor_common(vty, id, detail, isis,
sysid);
}
return 0;
return CMD_SUCCESS;
}
isis = isis_lookup_by_vrfname(vrf_name);
if (isis != NULL)
@ -863,7 +869,7 @@ int show_isis_neighbor_common(struct vty *vty, const char *id, char detail,
static void isis_neighbor_common_clear(struct vty *vty, const char *id,
uint8_t *sysid, struct isis *isis)
{
struct listnode *anode, *cnode, *cnextnode, *node, *nnode;
struct listnode *anode, *cnode, *node, *nnode;
struct isis_area *area;
struct isis_circuit *circuit;
struct list *adjdb;
@ -871,8 +877,7 @@ static void isis_neighbor_common_clear(struct vty *vty, const char *id,
int i;
for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
for (ALL_LIST_ELEMENTS(area->circuit_list, cnode, cnextnode,
circuit)) {
for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit)) {
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
for (i = 0; i < 2; i++) {
adjdb = circuit->u.bc.adjdb[i];
@ -910,10 +915,10 @@ static void isis_neighbor_common_clear(struct vty *vty, const char *id,
int clear_isis_neighbor_common(struct vty *vty, const char *id, const char *vrf_name,
bool all_vrf)
{
struct listnode *nnode, *inode;
struct listnode *node;
struct isis_dynhn *dynhn;
uint8_t sysid[ISIS_SYS_ID_LEN];
struct isis *isis = NULL;
struct isis *isis;
if (!im) {
vty_out(vty, "IS-IS Routing Process not enabled\n");
@ -933,11 +938,10 @@ int clear_isis_neighbor_common(struct vty *vty, const char *id, const char *vrf_
}
if (vrf_name) {
if (all_vrf) {
for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
isis_neighbor_common_clear(vty, id, sysid,
isis);
}
return 0;
return CMD_SUCCESS;
}
isis = isis_lookup_by_vrfname(vrf_name);
if (isis != NULL)
@ -1554,19 +1558,19 @@ DEFUN(show_hostname, show_hostname_cmd,
"All VRFs\n"
"IS-IS Dynamic hostname mapping\n")
{
struct listnode *nnode, *inode;
struct listnode *node;
const char *vrf_name = VRF_DEFAULT_NAME;
bool all_vrf = false;
int idx_vrf = 0;
struct isis *isis = NULL;
struct isis *isis;
ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
if (vrf_name) {
if (all_vrf) {
for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
dynhn_print_all(vty, isis);
}
return 0;
return CMD_SUCCESS;
}
isis = isis_lookup_by_vrfname(vrf_name);
if (isis != NULL)
@ -1621,8 +1625,8 @@ DEFUN(show_isis_spf_ietf, show_isis_spf_ietf_cmd,
"All VRFs\n"
"SPF delay IETF information\n")
{
struct listnode *nnode, *inode;
struct isis *isis = NULL;
struct listnode *node;
struct isis *isis;
int idx_vrf = 0;
const char *vrf_name = VRF_DEFAULT_NAME;
bool all_vrf = false;
@ -1636,10 +1640,10 @@ DEFUN(show_isis_spf_ietf, show_isis_spf_ietf_cmd,
if (vrf_name) {
if (all_vrf) {
for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
isis_spf_ietf_common(vty, isis);
}
return 0;
return CMD_SUCCESS;
}
isis = isis_lookup_by_vrfname(vrf_name);
if (isis != NULL)
@ -1755,9 +1759,9 @@ DEFUN(show_isis_summary, show_isis_summary_cmd,
"All VRFs\n"
"summary\n")
{
struct listnode *inode, *nnode;
struct listnode *node;
int idx_vrf = 0;
struct isis *isis = NULL;
struct isis *isis;
const char *vrf_name = VRF_DEFAULT_NAME;
bool all_vrf = false;
@ -1768,10 +1772,10 @@ DEFUN(show_isis_summary, show_isis_summary_cmd,
}
if (vrf_name) {
if (all_vrf) {
for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
common_isis_summary(vty, isis);
}
return 0;
return CMD_SUCCESS;
}
isis = isis_lookup_by_vrfname(vrf_name);
if (isis != NULL)
@ -1844,60 +1848,61 @@ struct isis_lsp *lsp_for_arg(struct lspdb_head *head, const char *argv,
return lsp;
}
static int show_isis_database_common(struct vty *vty, const char *argv,
int ui_level, struct isis *isis)
void show_isis_database_lspdb(struct vty *vty, struct isis_area *area,
int level, struct lspdb_head *lspdb,
const char *argv, int ui_level)
{
struct isis_lsp *lsp;
int lsp_count;
if (lspdb_count(lspdb) > 0) {
lsp = lsp_for_arg(lspdb, argv, area->isis);
if (lsp != NULL || argv == NULL) {
vty_out(vty, "IS-IS Level-%d link-state database:\n",
level + 1);
/* print the title in all cases */
vty_out(vty,
"LSP ID PduLen SeqNumber Chksum Holdtime ATT/P/OL\n");
}
if (lsp) {
if (ui_level == ISIS_UI_LEVEL_DETAIL)
lsp_print_detail(lsp, vty, area->dynhostname,
area->isis);
else
lsp_print(lsp, vty, area->dynhostname,
area->isis);
} else if (argv == NULL) {
lsp_count =
lsp_print_all(vty, lspdb, ui_level,
area->dynhostname, area->isis);
vty_out(vty, " %u LSPs\n\n", lsp_count);
}
}
}
static void show_isis_database_common(struct vty *vty, const char *argv,
int ui_level, struct isis *isis)
{
struct listnode *node;
struct isis_area *area;
struct isis_lsp *lsp;
int level, lsp_count;
int level;
if (isis->area_list->count == 0)
return CMD_SUCCESS;
return;
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
vty_out(vty, "Area %s:\n",
area->area_tag ? area->area_tag : "null");
for (level = 0; level < ISIS_LEVELS; level++) {
if (lspdb_count(&area->lspdb[level]) > 0) {
lsp = NULL;
lsp = lsp_for_arg(&area->lspdb[level], argv,
isis);
if (lsp != NULL || argv == NULL) {
vty_out(vty,
"IS-IS Level-%d link-state database:\n",
level + 1);
/* print the title in all cases */
vty_out(vty,
"LSP ID PduLen SeqNumber Chksum Holdtime ATT/P/OL\n");
}
if (lsp) {
if (ui_level == ISIS_UI_LEVEL_DETAIL)
lsp_print_detail(
lsp, vty,
area->dynhostname,
isis);
else
lsp_print(lsp, vty,
area->dynhostname,
isis);
} else if (argv == NULL) {
lsp_count = lsp_print_all(
vty, &area->lspdb[level],
ui_level, area->dynhostname,
isis);
vty_out(vty, " %u LSPs\n\n",
lsp_count);
}
}
}
for (level = 0; level < ISIS_LEVELS; level++)
show_isis_database_lspdb(vty, area, level,
&area->lspdb[level], argv,
ui_level);
}
return CMD_SUCCESS;
}
/*
* This function supports following display options:
@ -1918,19 +1923,19 @@ static int show_isis_database_common(struct vty *vty, const char *argv,
static int show_isis_database(struct vty *vty, const char *argv, int ui_level,
const char *vrf_name, bool all_vrf)
{
struct listnode *inode, *nnode;
struct isis *isis = NULL;
struct listnode *node;
struct isis *isis;
if (vrf_name) {
if (all_vrf) {
for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
show_isis_database_common(vty, argv, ui_level,
isis);
}
return 0;
return CMD_SUCCESS;
}
isis = isis_lookup_by_vrfname(vrf_name);
if (isis != NULL)
if (isis)
show_isis_database_common(vty, argv, ui_level, isis);
}
@ -2352,16 +2357,15 @@ static int isis_config_write(struct vty *vty)
{
int write = 0;
struct isis_area *area;
struct listnode *node, *node2, *inode, *nnode;
struct isis *isis = NULL;
struct listnode *node, *node2, *inode;
struct isis *isis;
if (!im) {
vty_out(vty, "IS-IS Routing Process not enabled\n");
return CMD_SUCCESS;
}
for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) {
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
/* ISIS - Area name */
vty_out(vty, "router " PROTO_NAME " %s\n", area->area_tag);

View File

@ -76,6 +76,7 @@ struct isis_master {
/* Various OSPF global configuration. */
uint8_t options;
};
#define F_ISIS_UNIT_TEST 0x01
struct isis {
vrf_id_t vrf_id;
@ -215,7 +216,7 @@ void isis_vrf_unlink(struct isis *isis, struct vrf *vrf);
void isis_global_instance_create(void);
struct isis *isis_lookup_by_vrfid(vrf_id_t vrf_id);
struct isis *isis_lookup_by_vrfname(const char *vrfname);
struct isis *isis_lookup_by_sysid(uint8_t *sysid);
struct isis *isis_lookup_by_sysid(const uint8_t *sysid);
void isis_init(void);
struct isis *isis_new(vrf_id_t vrf_id);
@ -247,6 +248,9 @@ int isis_area_passwd_cleartext_set(struct isis_area *area, int level,
const char *passwd, uint8_t snp_auth);
int isis_area_passwd_hmac_md5_set(struct isis_area *area, int level,
const char *passwd, uint8_t snp_auth);
void show_isis_database_lspdb(struct vty *vty, struct isis_area *area,
int level, struct lspdb_head *lspdb,
const char *argv, int ui_level);
/* YANG paths */
#define ISIS_INSTANCE "/frr-isisd:isis/instance"

1
tests/.gitignore vendored
View File

@ -13,6 +13,7 @@
/isisd/test_fuzz_isis_tlv
/isisd/test_fuzz_isis_tlv_tests.h
/isisd/test_isis_lspdb
/isisd/test_isis_spf
/isisd/test_isis_vertex_queue
/lib/cli/test_cli
/lib/cli/test_cli_clippy.c

331
tests/isisd/test_common.c Normal file
View File

@ -0,0 +1,331 @@
/*
* Copyright (C) 2020 NetDEF, Inc.
* Renato Westphal
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
#include "isisd/isisd.h"
#include "isisd/isis_dynhn.h"
#include "isisd/isis_mt.h"
#include "test_common.h"
struct thread_master *master;
struct zebra_privs_t isisd_privs;
int isis_sock_init(struct isis_circuit *circuit)
{
return 0;
}
const struct isis_test_node *
test_topology_find_node(const struct isis_topology *topology,
const char *hostname, uint8_t pseudonode_id)
{
for (size_t i = 0; topology->nodes[i].hostname[0]; i++)
if (strmatch(hostname, topology->nodes[i].hostname)
&& pseudonode_id == topology->nodes[i].pseudonode_id)
return &topology->nodes[i];
return NULL;
}
const struct isis_topology *
test_topology_find(struct isis_topology *test_topologies, uint16_t number)
{
for (size_t i = 0; test_topologies[i].number; i++)
if (test_topologies[i].number == number)
return &test_topologies[i];
return NULL;
}
static const struct isis_test_node *
test_find_adjacency(const struct isis_test_node *tnode, const char *hostname)
{
for (size_t i = 0; tnode->adjacencies[i].hostname[0]; i++) {
const struct isis_test_adj *tadj;
tadj = &tnode->adjacencies[i];
if (strmatch(hostname, tadj->hostname))
return tnode;
}
return NULL;
}
static struct isis_lsp *lsp_add(struct lspdb_head *lspdb,
struct isis_area *area, int level,
const uint8_t *sysid, uint8_t pseudonode_id)
{
struct isis_lsp *lsp;
uint8_t lspid[ISIS_SYS_ID_LEN + 2];
memcpy(lspid, sysid, ISIS_SYS_ID_LEN);
LSP_PSEUDO_ID(lspid) = pseudonode_id;
LSP_FRAGMENT(lspid) = 0;
lsp = lsp_new(area, lspid, 6000, 1, 0, 0, NULL, level);
lsp->tlvs = isis_alloc_tlvs();
lspdb_add(lspdb, lsp);
return lsp;
}
static void lsp_add_ip_reach(struct isis_lsp *lsp,
const struct isis_test_node *tnode,
const char *prefix_str, uint32_t *next_sid_index)
{
struct prefix prefix;
struct sr_prefix_cfg pcfg = {};
struct sr_prefix_cfg *pcfg_p = NULL;
if (str2prefix(prefix_str, &prefix) != 1) {
zlog_debug("%s: invalid network: %s", __func__, prefix_str);
return;
}
if (CHECK_FLAG(tnode->flags, F_ISIS_TEST_NODE_SR)) {
pcfg_p = &pcfg;
pcfg.sid = *next_sid_index;
*next_sid_index = *next_sid_index + 1;
pcfg.sid_type = SR_SID_VALUE_TYPE_INDEX;
pcfg.last_hop_behavior = SR_LAST_HOP_BEHAVIOR_PHP;
}
if (prefix.family == AF_INET)
isis_tlvs_add_extended_ip_reach(lsp->tlvs,
(struct prefix_ipv4 *)&prefix,
10, false, pcfg_p);
else
isis_tlvs_add_ipv6_reach(lsp->tlvs, ISIS_MT_IPV6_UNICAST,
(struct prefix_ipv6 *)&prefix, 10,
false, pcfg_p);
}
static void lsp_add_reach(struct isis_lsp *lsp,
const struct isis_test_node *tnode,
const uint8_t *ne_id, uint8_t pseudonode_id,
uint32_t metric, int family, mpls_label_t *next_label)
{
uint8_t nodeid[ISIS_SYS_ID_LEN + 1];
uint16_t mtid;
struct isis_ext_subtlvs *ext = NULL;
memcpy(nodeid, ne_id, ISIS_SYS_ID_LEN);
LSP_PSEUDO_ID(nodeid) = pseudonode_id;
if (CHECK_FLAG(tnode->flags, F_ISIS_TEST_NODE_SR)) {
struct isis_adj_sid *adj_sid;
adj_sid = XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*adj_sid));
adj_sid->family = family;
SET_FLAG(adj_sid->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG);
SET_FLAG(adj_sid->flags, EXT_SUBTLV_LINK_ADJ_SID_LFLG);
if (family == AF_INET6)
SET_FLAG(adj_sid->flags, EXT_SUBTLV_LINK_ADJ_SID_FFLG);
adj_sid->weight = 0;
adj_sid->sid = *next_label;
*next_label = *next_label + 1;
ext = isis_alloc_ext_subtlvs();
isis_tlvs_add_adj_sid(ext, adj_sid);
}
mtid = (family == AF_INET) ? ISIS_MT_IPV4_UNICAST
: ISIS_MT_IPV6_UNICAST;
isis_tlvs_add_extended_reach(lsp->tlvs, mtid, nodeid, metric, ext);
}
static void lsp_add_router_capability(struct isis_lsp *lsp,
const struct isis_test_node *tnode)
{
struct isis_router_cap cap = {};
if (!tnode->router_id)
return;
if (inet_pton(AF_INET, tnode->router_id, &cap.router_id) != 1) {
zlog_debug("%s: invalid router-id: %s", __func__,
tnode->router_id);
return;
}
if (CHECK_FLAG(tnode->flags, F_ISIS_TEST_NODE_SR)) {
cap.srgb.flags =
ISIS_SUBTLV_SRGB_FLAG_I | ISIS_SUBTLV_SRGB_FLAG_V;
cap.srgb.lower_bound = tnode->srgb.lower_bound
? tnode->srgb.lower_bound
: SRGB_DFTL_LOWER_BOUND;
cap.srgb.range_size = tnode->srgb.range_size
? tnode->srgb.range_size
: SRGB_DFTL_RANGE_SIZE;
cap.algo[0] = SR_ALGORITHM_SPF;
cap.algo[1] = SR_ALGORITHM_UNSET;
}
isis_tlvs_set_router_capability(lsp->tlvs, &cap);
}
static void lsp_add_mt_router_info(struct isis_lsp *lsp,
const struct isis_test_node *tnode)
{
if (tnode->protocols.ipv4)
isis_tlvs_add_mt_router_info(lsp->tlvs, ISIS_MT_IPV4_UNICAST, 0,
false);
if (tnode->protocols.ipv6)
isis_tlvs_add_mt_router_info(lsp->tlvs, ISIS_MT_IPV6_UNICAST, 0,
false);
}
static void lsp_add_protocols_supported(struct isis_lsp *lsp,
const struct isis_test_node *tnode)
{
struct nlpids nlpids = {};
if (!tnode->protocols.ipv4 && !tnode->protocols.ipv6)
return;
if (tnode->protocols.ipv4) {
nlpids.nlpids[nlpids.count] = NLPID_IP;
nlpids.count++;
}
if (tnode->protocols.ipv6) {
nlpids.nlpids[nlpids.count] = NLPID_IPV6;
nlpids.count++;
}
isis_tlvs_set_protocols_supported(lsp->tlvs, &nlpids);
}
static int topology_load_node_level(const struct isis_topology *topology,
const struct isis_test_node *tnode,
size_t tnode_index, struct isis_area *area,
struct lspdb_head *lspdb, int level)
{
struct isis_lsp *lsp;
uint32_t next_sid_index = (tnode_index + 1) * 10;
mpls_label_t next_label = 16;
lsp = lsp_add(lspdb, area, level, tnode->sysid, tnode->pseudonode_id);
lsp_add_mt_router_info(lsp, tnode);
lsp_add_protocols_supported(lsp, tnode);
lsp_add_router_capability(lsp, tnode);
/* Add IP Reachability Information. */
for (size_t i = 0; tnode->networks[i]; i++) {
if (i > MAX_NETWORKS) {
zlog_debug(
"%s: node has too many networks (maximum is %u)",
__func__, MAX_NETWORKS);
return -1;
}
lsp_add_ip_reach(lsp, tnode, tnode->networks[i],
&next_sid_index);
}
/* Add IS Reachability Information. */
for (size_t i = 0; tnode->adjacencies[i].hostname[0]; i++) {
const struct isis_test_adj *tadj;
const struct isis_test_node *tadj_node;
if (i > MAX_ADJACENCIES) {
zlog_debug(
"%s: node has too many adjacencies (maximum is %u)",
__func__, MAX_ADJACENCIES);
return -1;
}
tadj = &tnode->adjacencies[i];
tadj_node = test_topology_find_node(topology, tadj->hostname,
tadj->pseudonode_id);
if (!tadj_node) {
zlog_debug(
"%s: node \"%s\" has an adjacency with non-existing node \"%s\"",
__func__, tnode->hostname, tadj->hostname);
return -1;
}
if (!test_find_adjacency(tadj_node, tnode->hostname)) {
zlog_debug(
"%s: node \"%s\" has an one-way adjacency with node \"%s\"",
__func__, tnode->hostname, tadj->hostname);
return -1;
}
if (tnode->pseudonode_id || tadj_node->pseudonode_id
|| (tnode->protocols.ipv4 && tadj_node->protocols.ipv4))
lsp_add_reach(lsp, tnode, tadj_node->sysid,
tadj_node->pseudonode_id, tadj->metric,
AF_INET, &next_label);
if (tadj_node->pseudonode_id
|| (tnode->protocols.ipv6 && tadj_node->protocols.ipv6))
lsp_add_reach(lsp, tnode, tadj_node->sysid,
tadj_node->pseudonode_id, tadj->metric,
AF_INET6, &next_label);
}
return 0;
}
static int topology_load_node(const struct isis_topology *topology,
const struct isis_test_node *tnode,
size_t tnode_index, struct isis_area *area,
struct lspdb_head lspdb[])
{
int ret;
isis_dynhn_insert(tnode->sysid, tnode->hostname, tnode->level);
for (int level = IS_LEVEL_1; level <= IS_LEVEL_2; level++) {
if ((tnode->level & level) == 0)
continue;
ret = topology_load_node_level(topology, tnode, tnode_index,
area, &lspdb[level - 1], level);
if (ret != 0)
return ret;
}
return 0;
}
int test_topology_load(const struct isis_topology *topology,
struct isis_area *area, struct lspdb_head lspdb[])
{
for (int level = IS_LEVEL_1; level <= IS_LEVEL_2; level++)
lsp_db_init(&lspdb[level - 1]);
for (size_t i = 0; topology->nodes[i].hostname[0]; i++) {
const struct isis_test_node *tnode = &topology->nodes[i];
int ret;
if (i > MAX_NODES) {
zlog_debug(
"%s: topology has too many nodes (maximum is %u)",
__func__, MAX_NODES);
return -1;
}
ret = topology_load_node(topology, tnode, i, area, lspdb);
if (ret != 0)
return ret;
}
return 0;
}

82
tests/isisd/test_common.h Normal file
View File

@ -0,0 +1,82 @@
/*
* Copyright (C) 2020 NetDEF, Inc.
* Renato Westphal
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _COMMON_ISIS_H
#define _COMMON_ISIS_H
#include "isisd/isisd.h"
#include "isisd/isis_spf.h"
#include "isisd/isis_spf_private.h"
#define MAX_HOSTNAME 16
#define MAX_NETWORKS 8
#define MAX_ADJACENCIES 8
#define MAX_NODES 12
#define SRGB_DFTL_LOWER_BOUND 16000
#define SRGB_DFTL_RANGE_SIZE 8000
struct isis_test_adj {
char hostname[MAX_HOSTNAME];
uint8_t pseudonode_id;
uint32_t metric;
};
struct isis_test_node {
char hostname[MAX_HOSTNAME];
uint8_t sysid[ISIS_SYS_ID_LEN];
uint8_t pseudonode_id;
int level;
struct {
bool ipv4;
bool ipv6;
} protocols;
const char *router_id;
struct {
uint32_t lower_bound;
uint32_t range_size;
} srgb;
const char *networks[MAX_NETWORKS + 1];
struct isis_test_adj adjacencies[MAX_ADJACENCIES + 1];
uint8_t flags;
};
#define F_ISIS_TEST_NODE_SR 0x01
struct isis_topology {
uint16_t number;
struct isis_test_node nodes[MAX_NODES + 1];
};
/* Prototypes. */
extern int isis_sock_init(struct isis_circuit *circuit);
extern const struct isis_test_node *
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 int test_topology_load(const struct isis_topology *topology,
struct isis_area *area,
struct lspdb_head lspdb[]);
/* Global variables. */
extern struct thread_master *master;
extern struct zebra_privs_t isisd_privs;
extern struct isis_topology test_topologies[];
#endif /* _COMMON_ISIS_H */

View File

@ -14,17 +14,10 @@
#include "isisd/isis_circuit.h"
#include "isisd/isis_tlvs.h"
#include "test_common.h"
#define TEST_STREAM_SIZE 1500
struct thread_master *master;
int isis_sock_init(struct isis_circuit *circuit);
int isis_sock_init(struct isis_circuit *circuit)
{
return 0;
}
struct zebra_privs_t isisd_privs;
static bool atexit_registered;
static void show_meminfo_at_exit(void)

View File

@ -2,15 +2,7 @@
#include "isisd/isis_lsp.c"
struct thread_master *master;
int isis_sock_init(struct isis_circuit *circuit);
int isis_sock_init(struct isis_circuit *circuit)
{
return 0;
}
struct zebra_privs_t isisd_privs;
#include "test_common.h"
static void test_lsp_build_list_nonzero_ht(void)
{

313
tests/isisd/test_isis_spf.c Normal file
View File

@ -0,0 +1,313 @@
/*
* Copyright (C) 2020 NetDEF, Inc.
* Renato Westphal
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
#include <lib/version.h>
#include "getopt.h"
#include "thread.h"
#include "vty.h"
#include "command.h"
#include "log.h"
#include "vrf.h"
#include "yang.h"
#include "isisd/isisd.h"
#include "isisd/isis_dynhn.h"
#include "isisd/isis_misc.h"
#include "isisd/isis_spf.h"
#include "isisd/isis_spf_private.h"
#include "test_common.h"
enum test_type {
TEST_SPF = 1,
TEST_REVERSE_SPF,
};
#define F_DISPLAY_LSPDB 0x01
#define F_IPV4_ONLY 0x02
#define F_IPV6_ONLY 0x04
#define F_LEVEL1_ONLY 0x08
#define F_LEVEL2_ONLY 0x10
static struct isis *isis;
static void test_run_spf(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, bool reverse)
{
struct isis_spftree *spftree;
enum spf_type spf_type;
/* Run SPF. */
spf_type = reverse ? SPF_TYPE_REVERSE : SPF_TYPE_FORWARD;
spftree = isis_spftree_new(area, lspdb, root->sysid, level, tree,
spf_type, F_SPFTREE_NO_ADJACENCIES);
isis_run_spf(spftree);
/* Print the SPT and the corresponding routing table. */
isis_print_spftree(vty, spftree);
isis_print_routes(vty, spftree);
/* Cleanup SPF tree. */
isis_spftree_del(spftree);
}
static int test_run(struct vty *vty, const struct isis_topology *topology,
const struct isis_test_node *root, enum test_type test_type,
uint8_t flags)
{
struct isis_area *area;
/* Init topology. */
memcpy(isis->sysid, root->sysid, sizeof(isis->sysid));
area = isis_area_create("1", NULL);
area->is_type = IS_LEVEL_1_AND_2;
area->srdb.enabled = true;
if (test_topology_load(topology, area, area->lspdb) != 0) {
vty_out(vty, "%% Failed to load topology\n");
return CMD_WARNING;
}
for (int level = IS_LEVEL_1; level <= IS_LEVEL_2; level++) {
if (level == IS_LEVEL_1 && CHECK_FLAG(flags, F_LEVEL2_ONLY))
continue;
if (level == IS_LEVEL_2 && CHECK_FLAG(flags, F_LEVEL1_ONLY))
continue;
if ((root->level & level) == 0)
continue;
/* Print the LDPDB. */
if (CHECK_FLAG(flags, F_DISPLAY_LSPDB))
show_isis_database_lspdb(vty, area, level - 1,
&area->lspdb[level - 1], NULL,
ISIS_UI_LEVEL_DETAIL);
for (int tree = SPFTREE_IPV4; tree <= SPFTREE_IPV6; tree++) {
if (tree == SPFTREE_IPV4
&& CHECK_FLAG(flags, F_IPV6_ONLY))
continue;
if (tree == SPFTREE_IPV6
&& CHECK_FLAG(flags, F_IPV4_ONLY))
continue;
switch (test_type) {
case TEST_SPF:
test_run_spf(vty, topology, root, area,
&area->lspdb[level - 1], level,
tree, false);
break;
case TEST_REVERSE_SPF:
test_run_spf(vty, topology, root, area,
&area->lspdb[level - 1], level,
tree, true);
break;
}
}
}
/* Cleanup IS-IS area. */
isis_area_destroy(area);
/* Cleanup hostnames. */
dyn_cache_cleanup_all();
return CMD_SUCCESS;
}
DEFUN(test_isis, test_isis_cmd,
"test isis topology (1-13) root HOSTNAME\
<\
spf\
|reverse-spf\
>\
[display-lspdb] [<ipv4-only|ipv6-only>] [<level-1-only|level-2-only>]",
"Test command\n"
"IS-IS routing protocol\n"
"Test topology\n"
"Test topology number\n"
"SPF root\n"
"SPF root hostname\n"
"Normal Shortest Path First\n"
"Reverse Shortest Path First\n"
"Display the LSPDB\n"
"Do IPv4 processing only\n"
"Do IPv6 processing only\n"
"Skip L2 LSPs\n"
"Skip L1 LSPs\n")
{
uint16_t topology_number;
const struct isis_topology *topology;
const struct isis_test_node *root;
enum test_type test_type;
uint8_t flags = 0;
int idx = 0;
/* Load topology. */
argv_find(argv, argc, "topology", &idx);
topology_number = atoi(argv[idx + 1]->arg);
topology = test_topology_find(test_topologies, topology_number);
if (!topology) {
vty_out(vty, "%% Topology \"%s\" not found\n",
argv[idx + 1]->arg);
return CMD_WARNING;
}
/* Find root node. */
argv_find(argv, argc, "root", &idx);
root = test_topology_find_node(topology, argv[idx + 1]->arg, 0);
if (!root) {
vty_out(vty, "%% Node \"%s\" not found\n", argv[idx + 1]->arg);
return CMD_WARNING;
}
/* Parse test information. */
if (argv_find(argv, argc, "spf", &idx))
test_type = TEST_SPF;
else if (argv_find(argv, argc, "reverse-spf", &idx))
test_type = TEST_REVERSE_SPF;
else
return CMD_WARNING;
/* Parse control flags. */
if (argv_find(argv, argc, "display-lspdb", &idx))
SET_FLAG(flags, F_DISPLAY_LSPDB);
if (argv_find(argv, argc, "ipv4-only", &idx))
SET_FLAG(flags, F_IPV4_ONLY);
else if (argv_find(argv, argc, "ipv6-only", &idx))
SET_FLAG(flags, F_IPV6_ONLY);
if (argv_find(argv, argc, "level-1-only", &idx))
SET_FLAG(flags, F_LEVEL1_ONLY);
else if (argv_find(argv, argc, "level-2-only", &idx))
SET_FLAG(flags, F_LEVEL2_ONLY);
return test_run(vty, topology, root, test_type, flags);
}
static void vty_do_exit(int isexit)
{
printf("\nend.\n");
isis_finish(isis);
cmd_terminate();
vty_terminate();
yang_terminate();
thread_master_free(master);
log_memstats(stderr, "test-isis-spf");
if (!isexit)
exit(0);
}
struct option longopts[] = {{"help", no_argument, NULL, 'h'},
{"debug", no_argument, NULL, 'd'},
{0}};
/* Help information display. */
static void usage(char *progname, int status)
{
if (status != 0)
fprintf(stderr, "Try `%s --help' for more information.\n",
progname);
else {
printf("Usage : %s [OPTION...]\n\
isisd SPF test program.\n\n\
-u, --debug Enable debugging\n\
-h, --help Display this help and exit\n\
\n\
Report bugs to %s\n",
progname, FRR_BUG_ADDRESS);
}
exit(status);
}
int main(int argc, char **argv)
{
char *p;
char *progname;
struct thread thread;
bool debug = false;
/* Set umask before anything for security */
umask(0027);
/* get program name */
progname = ((p = strrchr(argv[0], '/')) ? ++p : argv[0]);
while (1) {
int opt;
opt = getopt_long(argc, argv, "hd", longopts, 0);
if (opt == EOF)
break;
switch (opt) {
case 0:
break;
case 'd':
debug = true;
break;
case 'h':
usage(progname, 0);
break;
default:
usage(progname, 1);
break;
}
}
/* master init. */
master = thread_master_create(NULL);
isis_master_init(master);
/* Library inits. */
cmd_init(1);
cmd_hostname_set("test");
vty_init(master, false);
yang_init(true);
if (debug)
zlog_aux_init("NONE: ", LOG_DEBUG);
else
zlog_aux_init("NONE: ", ZLOG_DISABLED);
/* IS-IS inits. */
yang_module_load("frr-isisd");
isis = isis_new(VRF_DEFAULT);
listnode_add(im->isis, isis);
SET_FLAG(im->options, F_ISIS_UNIT_TEST);
debug_spf_events |= DEBUG_SPF_EVENTS;
debug_events |= DEBUG_EVENTS;
debug_rte_events |= DEBUG_RTE_EVENTS;
/* Install test command. */
install_element(VIEW_NODE, &test_isis_cmd);
/* Read input from .in file. */
vty_stdio(vty_do_exit);
/* Fetch next active thread. */
while (thread_fetch(master, &thread))
thread_call(&thread);
/* Not reached. */
exit(0);
}

View File

@ -0,0 +1,16 @@
test isis topology 1 root rt1 spf
test isis topology 2 root rt1 spf
test isis topology 3 root rt1 spf ipv4-only
test isis topology 4 root rt1 spf ipv4-only
test isis topology 5 root rt1 spf ipv4-only
test isis topology 6 root rt1 spf ipv4-only
test isis topology 7 root rt1 spf ipv4-only
test isis topology 8 root rt1 spf ipv4-only
test isis topology 9 root rt1 spf
test isis topology 10 root rt1 spf
test isis topology 11 root rt1 spf
test isis topology 12 root rt1 spf ipv4-only
test isis topology 13 root rt1 spf ipv4-only
test isis topology 4 root rt1 reverse-spf ipv4-only
test isis topology 11 root rt1 reverse-spf

View File

@ -0,0 +1,4 @@
import frrtest
class TestIsisSPF(frrtest.TestRefOut):
program = './test_isis_spf'

View File

@ -0,0 +1,703 @@
test# test isis topology 1 root rt1 spf
IS-IS paths to level-1 routers that speak IP
Vertex Type Metric Next-Hop Interface Parent
rt1
10.0.255.1/32 IP internal 0 rt1(4)
rt2 TE-IS 10 rt2 - rt1(4)
rt3 TE-IS 10 rt3 - rt1(4)
rt4 TE-IS 20 rt2 - rt2(4)
rt5 TE-IS 20 rt3 - rt3(4)
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
10.0.255.3/32 IP TE 20 rt3 - rt3(4)
rt6 TE-IS 30 rt2 - rt4(4)
rt3 - rt5(4)
10.0.255.4/32 IP TE 30 rt2 - rt4(4)
10.0.255.5/32 IP TE 30 rt3 - rt5(4)
10.0.255.6/32 IP TE 40 rt2 - rt6(4)
rt3 -
IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------
10.0.255.2/32 20 - rt2 -
10.0.255.3/32 20 - rt3 -
10.0.255.4/32 30 - rt2 -
10.0.255.5/32 30 - rt3 -
10.0.255.6/32 40 - rt2 -
- rt3 -
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
rt1
2001:db8::1/128 IP6 internal 0 rt1(4)
rt2 TE-IS 10 rt2 - rt1(4)
rt3 TE-IS 10 rt3 - rt1(4)
rt4 TE-IS 20 rt2 - rt2(4)
rt5 TE-IS 20 rt3 - rt3(4)
2001:db8::2/128 IP6 internal 20 rt2 - rt2(4)
2001:db8::3/128 IP6 internal 20 rt3 - rt3(4)
rt6 TE-IS 30 rt2 - rt4(4)
rt3 - rt5(4)
2001:db8::4/128 IP6 internal 30 rt2 - rt4(4)
2001:db8::5/128 IP6 internal 30 rt3 - rt5(4)
2001:db8::6/128 IP6 internal 40 rt2 - rt6(4)
rt3 -
IS-IS L1 IPv6 routing table:
Prefix Metric Interface Nexthop Label(s)
-------------------------------------------------------
2001:db8::2/128 20 - rt2 -
2001:db8::3/128 20 - rt3 -
2001:db8::4/128 30 - rt2 -
2001:db8::5/128 30 - rt3 -
2001:db8::6/128 40 - rt2 -
- rt3 -
test# test isis topology 2 root rt1 spf
IS-IS paths to level-1 routers that speak IP
Vertex Type Metric Next-Hop Interface Parent
rt1
10.0.255.1/32 IP internal 0 rt1(4)
rt4 TE-IS 10 rt4 - rt1(4)
rt5 TE-IS 10 rt5 - rt1(4)
rt2 TE-IS 15 rt2 - rt1(4)
rt1
rt6 TE-IS 20 rt4 - rt4(4)
rt5 - rt5(4)
10.0.255.4/32 IP TE 20 rt4 - rt4(4)
10.0.255.5/32 IP TE 20 rt5 - rt5(4)
10.0.255.2/32 IP TE 25 rt2 - rt2(4)
rt3 TE-IS 30 rt3 - rt1(4)
10.0.255.6/32 IP TE 30 rt4 - rt6(4)
rt5 -
10.0.255.3/32 IP TE 40 rt3 - rt3(4)
IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------
10.0.255.2/32 25 - rt2 -
10.0.255.3/32 40 - rt3 -
10.0.255.4/32 20 - rt4 -
10.0.255.5/32 20 - rt5 -
10.0.255.6/32 30 - rt4 -
- rt5 -
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
rt1
2001:db8::1/128 IP6 internal 0 rt1(4)
rt4 TE-IS 10 rt4 - rt1(4)
rt5 TE-IS 10 rt5 - rt1(4)
rt2 TE-IS 15 rt2 - rt1(4)
rt1
rt6 TE-IS 20 rt4 - rt4(4)
rt5 - rt5(4)
2001:db8::4/128 IP6 internal 20 rt4 - rt4(4)
2001:db8::5/128 IP6 internal 20 rt5 - rt5(4)
2001:db8::2/128 IP6 internal 25 rt2 - rt2(4)
rt3 TE-IS 30 rt3 - rt1(4)
2001:db8::6/128 IP6 internal 30 rt4 - rt6(4)
rt5 -
2001:db8::3/128 IP6 internal 40 rt3 - rt3(4)
IS-IS L1 IPv6 routing table:
Prefix Metric Interface Nexthop Label(s)
-------------------------------------------------------
2001:db8::2/128 25 - rt2 -
2001:db8::3/128 40 - rt3 -
2001:db8::4/128 20 - rt4 -
2001:db8::5/128 20 - rt5 -
2001:db8::6/128 30 - rt4 -
- rt5 -
test# test isis topology 3 root rt1 spf ipv4-only
IS-IS paths to level-1 routers that speak IP
Vertex Type Metric Next-Hop Interface Parent
rt1
10.0.255.1/32 IP internal 0 rt1(4)
rt2 TE-IS 10 rt2 - rt1(4)
rt3 TE-IS 10 rt3 - rt1(4)
rt4 TE-IS 20 rt2 - rt2(4)
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
10.0.255.3/32 IP TE 20 rt3 - rt3(4)
rt5 TE-IS 30 rt2 - rt4(4)
rt6 TE-IS 30 rt2 - rt4(4)
10.0.255.4/32 IP TE 30 rt2 - rt4(4)
10.0.255.5/32 IP TE 40 rt2 - rt5(4)
10.0.255.6/32 IP TE 40 rt2 - rt6(4)
IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------
10.0.255.2/32 20 - rt2 -
10.0.255.3/32 20 - rt3 -
10.0.255.4/32 30 - rt2 -
10.0.255.5/32 40 - rt2 -
10.0.255.6/32 40 - rt2 -
test# test isis topology 4 root rt1 spf ipv4-only
IS-IS paths to level-1 routers that speak IP
Vertex Type Metric Next-Hop Interface Parent
rt1
10.0.255.1/32 IP internal 0 rt1(4)
rt2 TE-IS 10 rt2 - rt1(4)
rt3 TE-IS 10 rt3 - rt1(4)
rt4 TE-IS 20 rt2 - rt2(4)
rt5 TE-IS 20 rt3 - rt3(4)
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
10.0.255.3/32 IP TE 20 rt3 - rt3(4)
rt6 TE-IS 30 rt2 - rt4(4)
rt7 TE-IS 30 rt3 - rt5(4)
10.0.255.4/32 IP TE 30 rt2 - rt4(4)
10.0.255.5/32 IP TE 30 rt3 - rt5(4)
rt8 TE-IS 40 rt2 - rt6(4)
10.0.255.6/32 IP TE 40 rt2 - rt6(4)
10.0.255.7/32 IP TE 40 rt3 - rt7(4)
10.0.255.8/32 IP TE 50 rt2 - rt8(4)
IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------
10.0.255.2/32 20 - rt2 -
10.0.255.3/32 20 - rt3 -
10.0.255.4/32 30 - rt2 -
10.0.255.5/32 30 - rt3 -
10.0.255.6/32 40 - rt2 -
10.0.255.7/32 40 - rt3 -
10.0.255.8/32 50 - rt2 -
test# test isis topology 5 root rt1 spf ipv4-only
IS-IS paths to level-1 routers that speak IP
Vertex Type Metric Next-Hop Interface Parent
rt1
10.0.255.1/32 IP internal 0 rt1(4)
rt2 TE-IS 10 rt2 - rt1(4)
rt3 TE-IS 10 rt3 - rt1(4)
rt4 TE-IS 20 rt2 - rt2(4)
rt5 TE-IS 20 rt3 - rt3(4)
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
10.0.255.3/32 IP TE 20 rt3 - rt3(4)
rt6 TE-IS 30 rt2 - rt4(4)
rt7 TE-IS 30 rt3 - rt5(4)
10.0.255.4/32 IP TE 30 rt2 - rt4(4)
10.0.255.5/32 IP TE 30 rt3 - rt5(4)
rt8 TE-IS 40 rt2 - rt6(4)
rt3 - rt7(4)
10.0.255.6/32 IP TE 40 rt2 - rt6(4)
10.0.255.7/32 IP TE 40 rt3 - rt7(4)
10.0.255.8/32 IP TE 50 rt2 - rt8(4)
rt3 -
IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------
10.0.255.2/32 20 - rt2 -
10.0.255.3/32 20 - rt3 -
10.0.255.4/32 30 - rt2 -
10.0.255.5/32 30 - rt3 -
10.0.255.6/32 40 - rt2 -
10.0.255.7/32 40 - rt3 -
10.0.255.8/32 50 - rt2 -
- rt3 -
test# test isis topology 6 root rt1 spf ipv4-only
IS-IS paths to level-1 routers that speak IP
Vertex Type Metric Next-Hop Interface Parent
rt1
10.0.255.1/32 IP internal 0 rt1(4)
rt2 TE-IS 10 rt2 - rt1(4)
rt3 TE-IS 10 rt3 - rt1(4)
rt4 TE-IS 20 rt2 - rt2(4)
rt3 - rt3(4)
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
10.0.255.3/32 IP TE 20 rt3 - rt3(4)
rt6 TE-IS 30 rt2 - rt4(4)
rt3 -
10.0.255.4/32 IP TE 30 rt2 - rt4(4)
rt3 -
rt5 TE-IS 40 rt2 - rt6(4)
rt3 -
rt8 TE-IS 40 rt2 - rt6(4)
rt3 -
10.0.255.6/32 IP TE 40 rt2 - rt6(4)
rt3 -
rt7 TE-IS 50 rt2 - rt5(4)
rt3 - rt8(4)
10.0.255.5/32 IP TE 50 rt2 - rt5(4)
rt3 -
10.0.255.8/32 IP TE 50 rt2 - rt8(4)
rt3 -
10.0.255.7/32 IP TE 60 rt2 - rt7(4)
rt3 -
IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------
10.0.255.2/32 20 - rt2 -
10.0.255.3/32 20 - rt3 -
10.0.255.4/32 30 - rt2 -
- rt3 -
10.0.255.5/32 50 - rt2 -
- rt3 -
10.0.255.6/32 40 - rt2 -
- rt3 -
10.0.255.7/32 60 - rt2 -
- rt3 -
10.0.255.8/32 50 - rt2 -
- rt3 -
test# test isis topology 7 root rt1 spf ipv4-only
IS-IS paths to level-1 routers that speak IP
Vertex Type Metric Next-Hop Interface Parent
rt1
10.0.255.1/32 IP internal 0 rt1(4)
rt4 TE-IS 10 rt4 - rt1(4)
rt5 TE-IS 20 rt4 - rt4(4)
rt7 TE-IS 20 rt4 - rt4(4)
10.0.255.4/32 IP TE 20 rt4 - rt4(4)
rt2 TE-IS 30 rt4 - rt5(4)
rt6 TE-IS 30 rt4 - rt5(4)
rt8 TE-IS 30 rt4 - rt5(4)
rt7(4)
10.0.255.5/32 IP TE 30 rt4 - rt5(4)
10.0.255.7/32 IP TE 30 rt4 - rt7(4)
rt10 TE-IS 40 rt4 - rt7(4)
rt3 TE-IS 40 rt4 - rt2(4)
rt6(4)
rt9 TE-IS 40 rt4 - rt8(4)
rt11 TE-IS 40 rt4 - rt8(4)
10.0.255.2/32 IP TE 40 rt4 - rt2(4)
10.0.255.6/32 IP TE 40 rt4 - rt6(4)
10.0.255.8/32 IP TE 40 rt4 - rt8(4)
rt12 TE-IS 50 rt4 - rt9(4)
rt11(4)
10.0.255.10/32 IP TE 50 rt4 - rt10(4)
10.0.255.3/32 IP TE 50 rt4 - rt3(4)
10.0.255.9/32 IP TE 50 rt4 - rt9(4)
10.0.255.11/32 IP TE 50 rt4 - rt11(4)
10.0.255.12/32 IP TE 60 rt4 - rt12(4)
IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
------------------------------------------------------
10.0.255.2/32 40 - rt4 -
10.0.255.3/32 50 - rt4 -
10.0.255.4/32 20 - rt4 -
10.0.255.5/32 30 - rt4 -
10.0.255.6/32 40 - rt4 -
10.0.255.7/32 30 - rt4 -
10.0.255.8/32 40 - rt4 -
10.0.255.9/32 50 - rt4 -
10.0.255.10/32 50 - rt4 -
10.0.255.11/32 50 - rt4 -
10.0.255.12/32 60 - rt4 -
test# test isis topology 8 root rt1 spf ipv4-only
IS-IS paths to level-1 routers that speak IP
Vertex Type Metric Next-Hop Interface Parent
rt1
10.0.255.1/32 IP internal 0 rt1(4)
rt2 TE-IS 10 rt2 - rt1(4)
rt4 TE-IS 10 rt4 - rt1(4)
rt3 TE-IS 20 rt2 - rt2(4)
rt5 TE-IS 20 rt2 - rt2(4)
rt7 TE-IS 20 rt4 - rt4(4)
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
10.0.255.4/32 IP TE 20 rt4 - rt4(4)
rt6 TE-IS 30 rt2 - rt3(4)
rt5(4)
rt8 TE-IS 30 rt2 - rt5(4)
rt10 TE-IS 30 rt4 - rt7(4)
10.0.255.3/32 IP TE 30 rt2 - rt3(4)
10.0.255.5/32 IP TE 30 rt2 - rt5(4)
10.0.255.7/32 IP TE 30 rt4 - rt7(4)
rt9 TE-IS 40 rt2 - rt8(4)
rt11 TE-IS 40 rt2 - rt8(4)
10.0.255.6/32 IP TE 40 rt2 - rt6(4)
10.0.255.8/32 IP TE 40 rt2 - rt8(4)
10.0.255.10/32 IP TE 40 rt4 - rt10(4)
rt12 TE-IS 50 rt2 - rt9(4)
rt11(4)
10.0.255.9/32 IP TE 50 rt2 - rt9(4)
10.0.255.11/32 IP TE 50 rt2 - rt11(4)
10.0.255.12/32 IP TE 60 rt2 - rt12(4)
IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
------------------------------------------------------
10.0.255.2/32 20 - rt2 -
10.0.255.3/32 30 - rt2 -
10.0.255.4/32 20 - rt4 -
10.0.255.5/32 30 - rt2 -
10.0.255.6/32 40 - rt2 -
10.0.255.7/32 30 - rt4 -
10.0.255.8/32 40 - rt2 -
10.0.255.9/32 50 - rt2 -
10.0.255.10/32 40 - rt4 -
10.0.255.11/32 50 - rt2 -
10.0.255.12/32 60 - rt2 -
test# test isis topology 9 root rt1 spf
IS-IS paths to level-1 routers that speak IP
Vertex Type Metric Next-Hop Interface Parent
rt1
10.0.255.1/32 IP internal 0 rt1(4)
rt2 TE-IS 10 rt2 - rt1(4)
rt3 TE-IS 10 rt3 - rt1(4)
rt4 TE-IS 20 rt2 - rt2(4)
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
10.0.255.3/32 IP TE 20 rt3 - rt3(4)
rt5 TE-IS 30 rt2 - rt4(4)
10.0.255.4/32 IP TE 30 rt2 - rt4(4)
rt9 TE-IS 40 rt2 - rt5(4)
10.0.255.5/32 IP TE 40 rt2 - rt5(4)
rt6 TE-IS 50 rt2 - rt4(4)
rt9(4)
rt7 TE-IS 50 rt2 - rt4(4)
rt9(4)
rt8 TE-IS 50 rt2 - rt4(4)
rt9(4)
10.0.255.9/32 IP TE 50 rt2 - rt9(4)
10.0.255.6/32 IP TE 60 rt2 - rt6(4)
10.0.255.7/32 IP TE 60 rt2 - rt7(4)
10.0.255.8/32 IP TE 60 rt2 - rt8(4)
IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------
10.0.255.2/32 20 - rt2 -
10.0.255.3/32 20 - rt3 -
10.0.255.4/32 30 - rt2 -
10.0.255.5/32 40 - rt2 -
10.0.255.6/32 60 - rt2 -
10.0.255.7/32 60 - rt2 -
10.0.255.8/32 60 - rt2 -
10.0.255.9/32 50 - rt2 -
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
rt1
2001:db8::1/128 IP6 internal 0 rt1(4)
rt2 TE-IS 10 rt2 - rt1(4)
rt3 TE-IS 10 rt3 - rt1(4)
rt4 TE-IS 20 rt2 - rt2(4)
2001:db8::2/128 IP6 internal 20 rt2 - rt2(4)
2001:db8::3/128 IP6 internal 20 rt3 - rt3(4)
rt5 TE-IS 30 rt2 - rt4(4)
2001:db8::4/128 IP6 internal 30 rt2 - rt4(4)
rt9 TE-IS 40 rt2 - rt5(4)
2001:db8::5/128 IP6 internal 40 rt2 - rt5(4)
rt6 TE-IS 50 rt2 - rt4(4)
rt9(4)
rt7 TE-IS 50 rt2 - rt4(4)
rt9(4)
rt8 TE-IS 50 rt2 - rt4(4)
rt9(4)
2001:db8::9/128 IP6 internal 50 rt2 - rt9(4)
2001:db8::6/128 IP6 internal 60 rt2 - rt6(4)
2001:db8::7/128 IP6 internal 60 rt2 - rt7(4)
2001:db8::8/128 IP6 internal 60 rt2 - rt8(4)
IS-IS L1 IPv6 routing table:
Prefix Metric Interface Nexthop Label(s)
-------------------------------------------------------
2001:db8::2/128 20 - rt2 -
2001:db8::3/128 20 - rt3 -
2001:db8::4/128 30 - rt2 -
2001:db8::5/128 40 - rt2 -
2001:db8::6/128 60 - rt2 -
2001:db8::7/128 60 - rt2 -
2001:db8::8/128 60 - rt2 -
2001:db8::9/128 50 - rt2 -
test# test isis topology 10 root rt1 spf
IS-IS paths to level-1 routers that speak IP
Vertex Type Metric Next-Hop Interface Parent
rt1
10.0.255.1/32 IP internal 0 rt1(4)
rt2 TE-IS 10 rt2 - rt1(4)
rt3 TE-IS 20 rt3 - rt1(4)
rt4 TE-IS 20 rt4 - rt1(4)
rt5 TE-IS 20 rt2 - rt2(4)
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
rt6 TE-IS 30 rt3 - rt3(4)
rt7 TE-IS 30 rt4 - rt4(4)
rt8 TE-IS 30 rt2 - rt5(4)
10.0.255.3/32 IP TE 30 rt3 - rt3(4)
10.0.255.4/32 IP TE 30 rt4 - rt4(4)
10.0.255.5/32 IP TE 30 rt2 - rt5(4)
10.0.255.6/32 IP TE 40 rt3 - rt6(4)
10.0.255.7/32 IP TE 40 rt4 - rt7(4)
10.0.255.8/32 IP TE 40 rt2 - rt8(4)
IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------
10.0.255.2/32 20 - rt2 -
10.0.255.3/32 30 - rt3 -
10.0.255.4/32 30 - rt4 -
10.0.255.5/32 30 - rt2 -
10.0.255.6/32 40 - rt3 -
10.0.255.7/32 40 - rt4 -
10.0.255.8/32 40 - rt2 -
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
rt1
2001:db8::1/128 IP6 internal 0 rt1(4)
rt2 TE-IS 10 rt2 - rt1(4)
rt3 TE-IS 20 rt3 - rt1(4)
rt4 TE-IS 20 rt4 - rt1(4)
rt5 TE-IS 20 rt2 - rt2(4)
2001:db8::2/128 IP6 internal 20 rt2 - rt2(4)
rt6 TE-IS 30 rt3 - rt3(4)
rt7 TE-IS 30 rt4 - rt4(4)
rt8 TE-IS 30 rt2 - rt5(4)
2001:db8::3/128 IP6 internal 30 rt3 - rt3(4)
2001:db8::4/128 IP6 internal 30 rt4 - rt4(4)
2001:db8::5/128 IP6 internal 30 rt2 - rt5(4)
2001:db8::6/128 IP6 internal 40 rt3 - rt6(4)
2001:db8::7/128 IP6 internal 40 rt4 - rt7(4)
2001:db8::8/128 IP6 internal 40 rt2 - rt8(4)
IS-IS L1 IPv6 routing table:
Prefix Metric Interface Nexthop Label(s)
-------------------------------------------------------
2001:db8::2/128 20 - rt2 -
2001:db8::3/128 30 - rt3 -
2001:db8::4/128 30 - rt4 -
2001:db8::5/128 30 - rt2 -
2001:db8::6/128 40 - rt3 -
2001:db8::7/128 40 - rt4 -
2001:db8::8/128 40 - rt2 -
test# test isis topology 11 root rt1 spf
IS-IS paths to level-1 routers that speak IP
Vertex Type Metric Next-Hop Interface Parent
rt1
10.0.255.1/32 IP internal 0 rt1(4)
rt2 TE-IS 10 rt2 - rt1(4)
rt3 TE-IS 10 rt3 - rt1(4)
rt2 pseudo_TE-IS 20 rt3 - rt3(4)
rt4 TE-IS 20 rt2 - rt2(4)
rt5 TE-IS 20 rt3 - rt3(4)
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
10.0.255.3/32 IP TE 20 rt3 - rt3(4)
rt6 TE-IS 30 rt2 - rt4(4)
rt3 - rt5(4)
10.0.255.4/32 IP TE 30 rt2 - rt4(4)
10.0.255.5/32 IP TE 30 rt3 - rt5(4)
10.0.255.6/32 IP TE 40 rt2 - rt6(4)
rt3 -
IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------
10.0.255.2/32 20 - rt2 -
10.0.255.3/32 20 - rt3 -
10.0.255.4/32 30 - rt2 -
10.0.255.5/32 30 - rt3 -
10.0.255.6/32 40 - rt2 -
- rt3 -
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
rt1
2001:db8::1/128 IP6 internal 0 rt1(4)
rt2 TE-IS 10 rt2 - rt1(4)
rt3 TE-IS 10 rt3 - rt1(4)
rt2 pseudo_TE-IS 20 rt3 - rt3(4)
rt4 TE-IS 20 rt2 - rt2(4)
rt5 TE-IS 20 rt3 - rt3(4)
2001:db8::2/128 IP6 internal 20 rt2 - rt2(4)
2001:db8::3/128 IP6 internal 20 rt3 - rt3(4)
rt6 TE-IS 30 rt2 - rt4(4)
rt3 - rt5(4)
2001:db8::4/128 IP6 internal 30 rt2 - rt4(4)
2001:db8::5/128 IP6 internal 30 rt3 - rt5(4)
2001:db8::6/128 IP6 internal 40 rt2 - rt6(4)
rt3 -
IS-IS L1 IPv6 routing table:
Prefix Metric Interface Nexthop Label(s)
-------------------------------------------------------
2001:db8::2/128 20 - rt2 -
2001:db8::3/128 20 - rt3 -
2001:db8::4/128 30 - rt2 -
2001:db8::5/128 30 - rt3 -
2001:db8::6/128 40 - rt2 -
- rt3 -
test# test isis topology 12 root rt1 spf ipv4-only
IS-IS paths to level-1 routers that speak IP
Vertex Type Metric Next-Hop Interface Parent
rt1
10.0.255.1/32 IP internal 0 rt1(4)
rt2 TE-IS 10 rt2 - rt1(4)
rt3 TE-IS 10 rt3 - rt1(4)
rt4 TE-IS 20 rt2 - rt2(4)
rt5 TE-IS 20 rt3 - rt3(4)
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
10.0.255.3/32 IP TE 20 rt3 - rt3(4)
rt6 TE-IS 30 rt2 - rt4(4)
rt7 TE-IS 30 rt3 - rt5(4)
10.0.255.4/32 IP TE 30 rt2 - rt4(4)
10.0.255.5/32 IP TE 30 rt3 - rt5(4)
rt8 TE-IS 40 rt2 - rt6(4)
rt9 TE-IS 40 rt3 - rt7(4)
10.0.255.6/32 IP TE 40 rt2 - rt6(4)
10.0.255.7/32 IP TE 40 rt3 - rt7(4)
rt10 TE-IS 50 rt2 - rt8(4)
10.0.255.8/32 IP TE 50 rt2 - rt8(4)
10.0.255.9/32 IP TE 50 rt3 - rt9(4)
10.0.255.10/32 IP TE 60 rt2 - rt10(4)
IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
------------------------------------------------------
10.0.255.2/32 20 - rt2 -
10.0.255.3/32 20 - rt3 -
10.0.255.4/32 30 - rt2 -
10.0.255.5/32 30 - rt3 -
10.0.255.6/32 40 - rt2 -
10.0.255.7/32 40 - rt3 -
10.0.255.8/32 50 - rt2 -
10.0.255.9/32 50 - rt3 -
10.0.255.10/32 60 - rt2 -
test# test isis topology 13 root rt1 spf ipv4-only
IS-IS paths to level-1 routers that speak IP
Vertex Type Metric Next-Hop Interface Parent
rt1
10.0.255.1/32 IP internal 0 rt1(4)
rt2 TE-IS 10 rt2 - rt1(4)
rt3 TE-IS 10 rt3 - rt1(4)
rt4 TE-IS 20 rt2 - rt2(4)
rt3 - rt3(4)
rt5 TE-IS 20 rt3 - rt3(4)
rt6 TE-IS 20 rt3 - rt3(4)
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
10.0.255.3/32 IP TE 20 rt3 - rt3(4)
rt7 TE-IS 30 rt3 - rt5(4)
rt6(4)
10.0.255.4/32 IP TE 30 rt2 - rt4(4)
rt3 -
10.0.255.5/32 IP TE 30 rt3 - rt5(4)
10.0.255.6/32 IP TE 30 rt3 - rt6(4)
10.0.255.7/32 IP TE 40 rt3 - rt7(4)
IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------
10.0.255.2/32 20 - rt2 -
10.0.255.3/32 20 - rt3 -
10.0.255.4/32 30 - rt2 -
- rt3 -
10.0.255.5/32 30 - rt3 -
10.0.255.6/32 30 - rt3 -
10.0.255.7/32 40 - rt3 -
test#
test# test isis topology 4 root rt1 reverse-spf ipv4-only
IS-IS paths to level-1 routers that speak IP
Vertex Type Metric Next-Hop Interface Parent
rt1
10.0.255.1/32 IP internal 0 rt1(4)
rt2 TE-IS 10 rt2 - rt1(4)
rt3 TE-IS 10 rt3 - rt1(4)
rt4 TE-IS 20 rt2 - rt2(4)
rt5 TE-IS 20 rt3 - rt3(4)
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
10.0.255.3/32 IP TE 20 rt3 - rt3(4)
rt6 TE-IS 30 rt2 - rt4(4)
rt7 TE-IS 30 rt3 - rt5(4)
10.0.255.4/32 IP TE 30 rt2 - rt4(4)
10.0.255.5/32 IP TE 30 rt3 - rt5(4)
rt8 TE-IS 40 rt2 - rt6(4)
10.0.255.6/32 IP TE 40 rt2 - rt6(4)
10.0.255.7/32 IP TE 40 rt3 - rt7(4)
10.0.255.8/32 IP TE 50 rt2 - rt8(4)
IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------
10.0.255.2/32 20 - rt2 -
10.0.255.3/32 20 - rt3 -
10.0.255.4/32 30 - rt2 -
10.0.255.5/32 30 - rt3 -
10.0.255.6/32 40 - rt2 -
10.0.255.7/32 40 - rt3 -
10.0.255.8/32 50 - rt2 -
test# test isis topology 11 root rt1 reverse-spf
IS-IS paths to level-1 routers that speak IP
Vertex Type Metric Next-Hop Interface Parent
rt1
10.0.255.1/32 IP internal 0 rt1(4)
rt2 TE-IS 10 rt1(4)
rt3 TE-IS 10 rt3 - rt1(4)
rt2 pseudo_TE-IS 20 rt3 - rt3(4)
rt4 TE-IS 20 rt2(4)
rt5 TE-IS 20 rt3 - rt3(4)
10.0.255.2/32 IP TE 20 rt2(4)
10.0.255.3/32 IP TE 20 rt3 - rt3(4)
rt6 TE-IS 30 rt3 - rt4(4)
rt5(4)
10.0.255.4/32 IP TE 30 rt4(4)
10.0.255.5/32 IP TE 30 rt3 - rt5(4)
10.0.255.6/32 IP TE 40 rt3 - rt6(4)
IS-IS L1 IPv4 routing table:
Prefix Metric Interface Nexthop Label(s)
-----------------------------------------------------
10.0.255.3/32 20 - rt3 -
10.0.255.5/32 30 - rt3 -
10.0.255.6/32 40 - rt3 -
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
rt1
2001:db8::1/128 IP6 internal 0 rt1(4)
rt2 TE-IS 10 rt1(4)
rt3 TE-IS 10 rt3 - rt1(4)
rt2 pseudo_TE-IS 20 rt3 - rt3(4)
rt4 TE-IS 20 rt2(4)
rt5 TE-IS 20 rt3 - rt3(4)
2001:db8::2/128 IP6 internal 20 rt2(4)
2001:db8::3/128 IP6 internal 20 rt3 - rt3(4)
rt6 TE-IS 30 rt3 - rt4(4)
rt5(4)
2001:db8::4/128 IP6 internal 30 rt4(4)
2001:db8::5/128 IP6 internal 30 rt3 - rt5(4)
2001:db8::6/128 IP6 internal 40 rt3 - rt6(4)
IS-IS L1 IPv6 routing table:
Prefix Metric Interface Nexthop Label(s)
-------------------------------------------------------
2001:db8::3/128 20 - rt3 -
2001:db8::5/128 30 - rt3 -
2001:db8::6/128 40 - rt3 -
test#
end.

View File

@ -2,14 +2,7 @@
#include "isisd/isis_spf.c"
struct thread_master *master;
int isis_sock_init(struct isis_circuit *circuit);
int isis_sock_init(struct isis_circuit *circuit)
{
return 0;
}
struct zebra_privs_t isisd_privs;
#include "test_common.h"
static struct isis_vertex **vertices;
static size_t vertex_count;

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,7 @@ else
TESTS_ISISD = \
tests/isisd/test_fuzz_isis_tlv \
tests/isisd/test_isis_lspdb \
tests/isisd/test_isis_spf \
tests/isisd/test_isis_vertex_queue \
# end
endif
@ -111,6 +112,7 @@ noinst_HEADERS += \
tests/helpers/c/tests.h \
tests/lib/cli/common_cli.h \
tests/lib/test_typelist.h \
tests/isisd/test_common.h \
# end
#
@ -168,16 +170,21 @@ tests_bgpd_test_peer_attr_SOURCES = tests/bgpd/test_peer_attr.c
tests_isisd_test_fuzz_isis_tlv_CFLAGS = $(TESTS_CFLAGS) -I$(top_builddir)/tests/isisd
tests_isisd_test_fuzz_isis_tlv_CPPFLAGS = $(TESTS_CPPFLAGS) -I$(top_builddir)/tests/isisd
tests_isisd_test_fuzz_isis_tlv_LDADD = $(ISISD_TEST_LDADD)
tests_isisd_test_fuzz_isis_tlv_SOURCES = tests/isisd/test_fuzz_isis_tlv.c
tests_isisd_test_fuzz_isis_tlv_SOURCES = tests/isisd/test_fuzz_isis_tlv.c tests/isisd/test_common.c
nodist_tests_isisd_test_fuzz_isis_tlv_SOURCES = tests/isisd/test_fuzz_isis_tlv_tests.h
tests_isisd_test_isis_lspdb_CFLAGS = $(TESTS_CFLAGS)
tests_isisd_test_isis_lspdb_CPPFLAGS = $(TESTS_CPPFLAGS)
tests_isisd_test_isis_lspdb_LDADD = $(ISISD_TEST_LDADD)
tests_isisd_test_isis_lspdb_SOURCES = tests/isisd/test_isis_lspdb.c
tests_isisd_test_isis_lspdb_SOURCES = tests/isisd/test_isis_lspdb.c tests/isisd/test_common.c
tests_isisd_test_isis_spf_CFLAGS = $(TESTS_CFLAGS)
tests_isisd_test_isis_spf_CPPFLAGS = $(TESTS_CPPFLAGS)
tests_isisd_test_isis_spf_LDADD = $(ISISD_TEST_LDADD)
tests_isisd_test_isis_spf_SOURCES = tests/isisd/test_isis_spf.c tests/isisd/test_common.c tests/isisd/test_topologies.c
nodist_tests_isisd_test_isis_spf_SOURCES = yang/frr-isisd.yang.c
tests_isisd_test_isis_vertex_queue_CFLAGS = $(TESTS_CFLAGS)
tests_isisd_test_isis_vertex_queue_CPPFLAGS = $(TESTS_CPPFLAGS)
tests_isisd_test_isis_vertex_queue_LDADD = $(ISISD_TEST_LDADD)
tests_isisd_test_isis_vertex_queue_SOURCES = tests/isisd/test_isis_vertex_queue.c
tests_isisd_test_isis_vertex_queue_SOURCES = tests/isisd/test_isis_vertex_queue.c tests/isisd/test_common.c
tests_lib_cxxcompat_CFLAGS = $(TESTS_CFLAGS) $(CXX_COMPAT_CFLAGS) $(WERROR)
tests_lib_cxxcompat_CPPFLAGS = $(TESTS_CPPFLAGS)
@ -327,6 +334,9 @@ EXTRA_DIST += \
tests/isisd/test_fuzz_isis_tlv.py \
tests/isisd/test_fuzz_isis_tlv_tests.h.gz \
tests/isisd/test_isis_lspdb.py \
tests/isisd/test_isis_spf.py \
tests/isisd/test_isis_spf.in \
tests/isisd/test_isis_spf.refout \
tests/isisd/test_isis_vertex_queue.py \
tests/lib/cli/test_commands.in \
tests/lib/cli/test_commands.py \